xyeger 0.3.4 → 1.0.0.rc
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 +4 -4
- data/.rubocop.yml +65 -0
- data/Gemfile.lock +102 -0
- data/README.md +219 -132
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/xyeger/config.rb +8 -12
- data/lib/xyeger/context.rb +19 -0
- data/lib/xyeger/context_resolver.rb +12 -0
- data/lib/xyeger/formatters/base.rb +14 -40
- data/lib/xyeger/formatters/json.rb +2 -1
- data/lib/xyeger/formatters/text.rb +20 -0
- data/lib/xyeger/formatters/values.rb +1 -1
- data/lib/xyeger/formatters.rb +4 -11
- data/lib/xyeger/integrations/rails.rb +35 -0
- data/lib/xyeger/integrations/sidekiq.rb +38 -0
- data/lib/xyeger/logger.rb +13 -13
- data/lib/xyeger/message_resolver.rb +14 -0
- data/lib/xyeger/middlewares/clear_context.rb +15 -0
- data/lib/xyeger/version.rb +1 -1
- data/lib/xyeger.rb +15 -33
- data/xyeger.gemspec +11 -14
- metadata +14 -37
- data/CODE_OF_CONDUCT.md +0 -74
- data/lib/xyeger/formatters/key_value.rb +0 -11
- data/lib/xyeger/formatters/lograge_raw.rb +0 -6
- data/lib/xyeger/formatters/sidekiq_json.rb +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e0455bfab0a7b4d2b8a48cdf8ddd6d0fd70a9102
|
|
4
|
+
data.tar.gz: e53aa11125c2073b0016e7bc91fa1d37f2105958
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b92dca5942df0257ac51ff47d031ec86ce757810c0ae1444350b9ace0551da175ca99c14de456d1cfe8301a33c2163c665b638cf46882c8dcac4603910ca2377
|
|
7
|
+
data.tar.gz: 0c6297439b58999e9c5a218ce773a30987394444282c8b9f6f5160e311318ae9938485db524d71a74586e0eccf2989ca2ac5a3f8a4a353ba7eee7314fdefc67c
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
TargetRubyVersion: 2.3
|
|
3
|
+
DisplayCopNames: true
|
|
4
|
+
Exclude:
|
|
5
|
+
- bin/*
|
|
6
|
+
- vendor/**/*
|
|
7
|
+
- spec/spec_helper.rb
|
|
8
|
+
- spec/rails_helper.rb
|
|
9
|
+
|
|
10
|
+
Metrics/LineLength:
|
|
11
|
+
Max: 120
|
|
12
|
+
|
|
13
|
+
Metrics/ParameterLists:
|
|
14
|
+
Enabled: false
|
|
15
|
+
|
|
16
|
+
Metrics/BlockLength:
|
|
17
|
+
Exclude:
|
|
18
|
+
- spec/**/*
|
|
19
|
+
- xyeger.gemspec
|
|
20
|
+
|
|
21
|
+
Style/Alias:
|
|
22
|
+
EnforcedStyle: prefer_alias_method
|
|
23
|
+
|
|
24
|
+
Style/AlignParameters:
|
|
25
|
+
EnforcedStyle: with_fixed_indentation
|
|
26
|
+
|
|
27
|
+
Style/BlockDelimiters:
|
|
28
|
+
EnforcedStyle: braces_for_chaining
|
|
29
|
+
|
|
30
|
+
Style/Documentation:
|
|
31
|
+
Enabled: false
|
|
32
|
+
|
|
33
|
+
Style/DoubleNegation:
|
|
34
|
+
Enabled: false
|
|
35
|
+
|
|
36
|
+
Style/FirstParameterIndentation:
|
|
37
|
+
EnforcedStyle: consistent
|
|
38
|
+
|
|
39
|
+
Style/FrozenStringLiteralComment:
|
|
40
|
+
Enabled: false
|
|
41
|
+
|
|
42
|
+
Style/GuardClause:
|
|
43
|
+
Enabled: false
|
|
44
|
+
|
|
45
|
+
Style/EmptyMethod:
|
|
46
|
+
EnforcedStyle: expanded
|
|
47
|
+
|
|
48
|
+
Style/IfUnlessModifier:
|
|
49
|
+
Enabled: false
|
|
50
|
+
|
|
51
|
+
Style/IndentArray:
|
|
52
|
+
EnforcedStyle: consistent
|
|
53
|
+
|
|
54
|
+
Style/IndentHash:
|
|
55
|
+
EnforcedStyle: consistent
|
|
56
|
+
|
|
57
|
+
Style/ModuleFunction:
|
|
58
|
+
Enabled: false
|
|
59
|
+
|
|
60
|
+
Style/RescueModifier:
|
|
61
|
+
Exclude:
|
|
62
|
+
- spec/**/*
|
|
63
|
+
|
|
64
|
+
Style/TrailingUnderscoreVariable:
|
|
65
|
+
Enabled: false
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
xyeger (0.3.4)
|
|
5
|
+
actionpack (>= 4)
|
|
6
|
+
activesupport (>= 4)
|
|
7
|
+
railties (>= 4)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
actionpack (5.1.2)
|
|
13
|
+
actionview (= 5.1.2)
|
|
14
|
+
activesupport (= 5.1.2)
|
|
15
|
+
rack (~> 2.0)
|
|
16
|
+
rack-test (~> 0.6.3)
|
|
17
|
+
rails-dom-testing (~> 2.0)
|
|
18
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
19
|
+
actionview (5.1.2)
|
|
20
|
+
activesupport (= 5.1.2)
|
|
21
|
+
builder (~> 3.1)
|
|
22
|
+
erubi (~> 1.4)
|
|
23
|
+
rails-dom-testing (~> 2.0)
|
|
24
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
25
|
+
activesupport (5.1.2)
|
|
26
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
27
|
+
i18n (~> 0.7)
|
|
28
|
+
minitest (~> 5.1)
|
|
29
|
+
tzinfo (~> 1.1)
|
|
30
|
+
ast (2.3.0)
|
|
31
|
+
builder (3.2.3)
|
|
32
|
+
concurrent-ruby (1.0.5)
|
|
33
|
+
diff-lcs (1.3)
|
|
34
|
+
erubi (1.6.1)
|
|
35
|
+
i18n (0.8.6)
|
|
36
|
+
loofah (2.0.3)
|
|
37
|
+
nokogiri (>= 1.5.9)
|
|
38
|
+
method_source (0.8.2)
|
|
39
|
+
mini_portile2 (2.2.0)
|
|
40
|
+
minitest (5.10.3)
|
|
41
|
+
nokogiri (1.8.0)
|
|
42
|
+
mini_portile2 (~> 2.2.0)
|
|
43
|
+
parallel (1.11.2)
|
|
44
|
+
parser (2.4.0.0)
|
|
45
|
+
ast (~> 2.2)
|
|
46
|
+
powerpack (0.1.1)
|
|
47
|
+
rack (2.0.3)
|
|
48
|
+
rack-test (0.6.3)
|
|
49
|
+
rack (>= 1.0)
|
|
50
|
+
rails-dom-testing (2.0.3)
|
|
51
|
+
activesupport (>= 4.2.0)
|
|
52
|
+
nokogiri (>= 1.6)
|
|
53
|
+
rails-html-sanitizer (1.0.3)
|
|
54
|
+
loofah (~> 2.0)
|
|
55
|
+
railties (5.1.2)
|
|
56
|
+
actionpack (= 5.1.2)
|
|
57
|
+
activesupport (= 5.1.2)
|
|
58
|
+
method_source
|
|
59
|
+
rake (>= 0.8.7)
|
|
60
|
+
thor (>= 0.18.1, < 2.0)
|
|
61
|
+
rainbow (2.2.2)
|
|
62
|
+
rake
|
|
63
|
+
rake (10.5.0)
|
|
64
|
+
rspec (3.6.0)
|
|
65
|
+
rspec-core (~> 3.6.0)
|
|
66
|
+
rspec-expectations (~> 3.6.0)
|
|
67
|
+
rspec-mocks (~> 3.6.0)
|
|
68
|
+
rspec-core (3.6.0)
|
|
69
|
+
rspec-support (~> 3.6.0)
|
|
70
|
+
rspec-expectations (3.6.0)
|
|
71
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
72
|
+
rspec-support (~> 3.6.0)
|
|
73
|
+
rspec-mocks (3.6.0)
|
|
74
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
75
|
+
rspec-support (~> 3.6.0)
|
|
76
|
+
rspec-support (3.6.0)
|
|
77
|
+
rubocop (0.49.1)
|
|
78
|
+
parallel (~> 1.10)
|
|
79
|
+
parser (>= 2.3.3.1, < 3.0)
|
|
80
|
+
powerpack (~> 0.1)
|
|
81
|
+
rainbow (>= 1.99.1, < 3.0)
|
|
82
|
+
ruby-progressbar (~> 1.7)
|
|
83
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
84
|
+
ruby-progressbar (1.8.1)
|
|
85
|
+
thor (0.19.4)
|
|
86
|
+
thread_safe (0.3.6)
|
|
87
|
+
tzinfo (1.2.3)
|
|
88
|
+
thread_safe (~> 0.1)
|
|
89
|
+
unicode-display_width (1.3.0)
|
|
90
|
+
|
|
91
|
+
PLATFORMS
|
|
92
|
+
ruby
|
|
93
|
+
|
|
94
|
+
DEPENDENCIES
|
|
95
|
+
bundler (~> 1.14)
|
|
96
|
+
rake (~> 10.0)
|
|
97
|
+
rspec (~> 3.0)
|
|
98
|
+
rubocop
|
|
99
|
+
xyeger!
|
|
100
|
+
|
|
101
|
+
BUNDLED WITH
|
|
102
|
+
1.15.1
|
data/README.md
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
# Xyeger
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Table of content
|
|
4
|
+
|
|
5
|
+
- [Basic Usage](#basic-usage)
|
|
6
|
+
- [Installation](#installation)
|
|
7
|
+
- [Configuration](#configuration)
|
|
8
|
+
- [Context](#context)
|
|
9
|
+
- [Context Resolver](#context-resolver)
|
|
10
|
+
- [Message Resolver](#message-resolver)
|
|
11
|
+
- [Formatters](#formatters)
|
|
12
|
+
- [Base Formatter](#base-formatter)
|
|
13
|
+
- [JSON Formatter](#json-formatter)
|
|
14
|
+
- [Values Formatter](#values-formatter)
|
|
15
|
+
- [Text Formatter](#text-formatter)
|
|
16
|
+
- [Custom Formatter](#custom-formatter)
|
|
17
|
+
- [Integrations](#integrations)
|
|
18
|
+
- [Rails](#rails)
|
|
19
|
+
- [Grape](#grape)
|
|
20
|
+
- [Sidekiq](#sidekiq)
|
|
21
|
+
- [Sentry](#sentry)
|
|
22
|
+
- [Plain ruby app](#plain-ruby-app)
|
|
23
|
+
## Basic Usage
|
|
24
|
+
Xyeger Logger was created to be suitable with ElasticSearch logs, so when you log anything you will get JSON representation of your message.
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
Xyeger.configure {}
|
|
28
|
+
logger = Logger.new(STDOUT)
|
|
29
|
+
logger.extend(Xyeger::Logger)
|
|
30
|
+
logger.info('Some message')
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"hostname": "",
|
|
36
|
+
"pid": 61915,
|
|
37
|
+
"app": "",
|
|
38
|
+
"env": "",
|
|
39
|
+
"level": "INFO",
|
|
40
|
+
"time": "2017-08-03 16:24:57 +0300",
|
|
41
|
+
"message": "Some message",
|
|
42
|
+
"context": {}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Installation
|
|
4
47
|
|
|
5
48
|
Add this line to your application's Gemfile:
|
|
6
49
|
|
|
@@ -16,183 +59,227 @@ Or install it yourself as:
|
|
|
16
59
|
|
|
17
60
|
$ gem install xyeger
|
|
18
61
|
|
|
19
|
-
## Usage
|
|
20
|
-
|
|
21
62
|
### Configuration
|
|
22
63
|
|
|
23
64
|
Add environments:
|
|
65
|
+
|
|
24
66
|
```bash
|
|
25
|
-
XYEGER_HOSTNAME='
|
|
67
|
+
XYEGER_HOSTNAME='localhost' #f.e.: rails, sidekiq, sneakers
|
|
68
|
+
XYEGER_APPNAME='some_service'
|
|
69
|
+
XYEGER_ENV='staging'
|
|
26
70
|
```
|
|
27
71
|
|
|
28
72
|
Add into initializer file:
|
|
29
|
-
```ruby
|
|
30
|
-
#config/initializers/xyeger.rb
|
|
31
|
-
Xyeger.configure do |config|
|
|
32
|
-
config.filter_parameters = Rails.application.config.filter_parameters
|
|
33
|
-
end
|
|
34
|
-
```
|
|
35
|
-
| Formatter | Description | Options |
|
|
36
|
-
| ---------------------------- | ---------------- | ------- |
|
|
37
|
-
| `Xyeger::Formatters::Base` | | colored |
|
|
38
|
-
| `Xyeger::Formatters::Json` | default format | colored |
|
|
39
|
-
| `Xyeger::Formatters::Values` | show only values | colored |
|
|
40
73
|
|
|
41
|
-
Default options:
|
|
42
74
|
```ruby
|
|
43
75
|
#config/initializers/xyeger.rb
|
|
44
76
|
Xyeger.configure do |config|
|
|
45
|
-
config.output = STDOUT
|
|
46
|
-
config.formatter = Xyeger::Formatters::
|
|
47
|
-
config.
|
|
48
|
-
config.
|
|
49
|
-
config.
|
|
50
|
-
config.
|
|
77
|
+
config.output = STDOUT # default to STDOUT
|
|
78
|
+
config.formatter = MyCustomFormatter # default to Xyeger::Formatters::Json.new
|
|
79
|
+
config.app = '' # default to ENV['XYEGER_APPNAME'] or emtpy string
|
|
80
|
+
config.env = Rails.env # default to ENV['XYEGER_ENV'] or empty string
|
|
81
|
+
config.context_resolver = MyContextResolver # ContextResolver class
|
|
82
|
+
config.message_resolver = MyMessageResolver # MessageResolver class
|
|
51
83
|
end
|
|
52
84
|
```
|
|
53
85
|
|
|
54
|
-
|
|
86
|
+
### Context
|
|
87
|
+
It was found out that just JSON-looking logs does not solve the problem of tracking request flow. So context was added.
|
|
88
|
+
|
|
55
89
|
```ruby
|
|
56
|
-
|
|
90
|
+
Xyeger.add_context(flow_id: SecureRandom.uuid)
|
|
91
|
+
logger.debug('With Context')
|
|
57
92
|
```
|
|
58
93
|
|
|
59
|
-
## Output results
|
|
60
|
-
|
|
61
|
-
### Http request
|
|
62
|
-
```bash
|
|
63
|
-
curl localhost:3000 -G -d a=3
|
|
64
|
-
```
|
|
65
94
|
```json
|
|
66
95
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
"path": "/",
|
|
78
|
-
"format": "*/*",
|
|
79
|
-
"controller": "PagesController",
|
|
80
|
-
"action": "index",
|
|
81
|
-
"status": 200,
|
|
82
|
-
"duration": 1852.79,
|
|
83
|
-
"view": 703.55,
|
|
84
|
-
"db": 29.07,
|
|
85
|
-
"params": {"a": "3"}}
|
|
96
|
+
"hostname": "",
|
|
97
|
+
"pid": 61915,
|
|
98
|
+
"app": "",
|
|
99
|
+
"env": "",
|
|
100
|
+
"level": "DEBUG",
|
|
101
|
+
"time": "2017-08-03 16:26:38 +0300",
|
|
102
|
+
"message": "With Context",
|
|
103
|
+
"context": {
|
|
104
|
+
"flow_id": "6821a053-ad20-4d58-905a-25a923f7a412"
|
|
105
|
+
}
|
|
86
106
|
}
|
|
87
107
|
```
|
|
88
108
|
|
|
89
|
-
###
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
109
|
+
### Context Resolver
|
|
110
|
+
|
|
111
|
+
You are not wired to add only hash object to context, but in that keys you might want to create your own `ContextResolver`, which expect `self.call(object)` method and return hash-representation at the end.
|
|
112
|
+
|
|
113
|
+
```ruby
|
|
114
|
+
class MyContextResolver
|
|
115
|
+
def self.call(object)
|
|
116
|
+
case object
|
|
117
|
+
when User
|
|
118
|
+
{ user_id: object.uuid }
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
Xyeger.configure { config.context_resolver = MyContextResolver }
|
|
124
|
+
|
|
125
|
+
user = User.first
|
|
126
|
+
Xyeger.add_context(user)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Message Resolver
|
|
130
|
+
|
|
131
|
+
Same way as it is done in context resolver you might find useful to create your own `MessageResolver`, which expect `self.call(message, progname)` method to be implemented and return string at the end.
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
class MessageResolver
|
|
135
|
+
def self.call(message, progname)
|
|
136
|
+
message =
|
|
137
|
+
case message
|
|
138
|
+
when ::StandardError
|
|
139
|
+
[message.class.name, message].compact.join(' ')
|
|
140
|
+
else
|
|
141
|
+
message.to_s
|
|
142
|
+
end
|
|
143
|
+
[progname, message].compact.join(' ')
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
Xyeger.configure { config.message_resolver = MyContextResolver }
|
|
148
|
+
|
|
149
|
+
begin
|
|
150
|
+
raise
|
|
151
|
+
rescue => error
|
|
152
|
+
Xyeger.add_context(error)
|
|
153
|
+
raise error
|
|
154
|
+
end
|
|
106
155
|
```
|
|
107
156
|
|
|
108
|
-
|
|
157
|
+
|
|
158
|
+
## Formatters
|
|
159
|
+
By default you have following formatters
|
|
160
|
+
|
|
161
|
+
| Formatter | Description |
|
|
162
|
+
| ---------------------------- | ---------------- |
|
|
163
|
+
| `Xyeger::Formatters::Base` | |
|
|
164
|
+
| `Xyeger::Formatters::Json` | default formater |
|
|
165
|
+
| `Xyeger::Formatters::Values` | show only values |
|
|
166
|
+
| `Xyeger::Formatters::Text` | show text form |
|
|
167
|
+
|
|
168
|
+
### Base formatter
|
|
169
|
+
All built-in formatters inherit from `Xyeger::Formatters::Base`, which prepare result hash with following keys: `hostname`, `pid`, `app`, `env`, `level`, `time`, `message`, `context`.
|
|
170
|
+
|
|
171
|
+
### JSON Formatter
|
|
172
|
+
Default representation of logs:
|
|
173
|
+
|
|
109
174
|
```ruby
|
|
110
|
-
|
|
175
|
+
logger.formatter = Xyeger::Formatters::Json.new # default formatter
|
|
111
176
|
```
|
|
112
177
|
```json
|
|
113
178
|
{
|
|
114
|
-
"
|
|
115
|
-
"pid":
|
|
116
|
-
"app":"
|
|
117
|
-
"env":"
|
|
118
|
-
"level":"
|
|
119
|
-
"time":"2017-
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
{
|
|
124
|
-
"content":"1",
|
|
125
|
-
"params":"b"
|
|
179
|
+
"hostname": "",
|
|
180
|
+
"pid": 61915,
|
|
181
|
+
"app": "",
|
|
182
|
+
"env": "",
|
|
183
|
+
"level": "DEBUG",
|
|
184
|
+
"time": "2017-08-03 16:26:38 +0300",
|
|
185
|
+
"message": "With Context ",
|
|
186
|
+
"context": {
|
|
187
|
+
"flow_id": "6821a053-ad20-4d58-905a-25a923f7a412"
|
|
126
188
|
}
|
|
127
189
|
}
|
|
190
|
+
```
|
|
128
191
|
|
|
192
|
+
### Values Formatter
|
|
193
|
+
All the values of Base formatter hash concatenated with `space` delimiter.
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
logger.formatter = Xyeger::Formatters::Values.new
|
|
197
|
+
```
|
|
129
198
|
```
|
|
199
|
+
61915 DEBUG 2017-08-03 17:00:07 +0300 With Context {:flow_id=>"6821a053-ad20-4d58-905a-25a923f7a412"}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Text Formatter
|
|
203
|
+
Context represented via list of key-value. Message is just string at the end
|
|
130
204
|
|
|
131
|
-
## Grape usage
|
|
132
|
-
WIth ```gem 'grape_logging'```
|
|
133
205
|
```ruby
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# "status":200,
|
|
137
|
-
# "time":
|
|
138
|
-
# {
|
|
139
|
-
# "total":86.84,
|
|
140
|
-
# "db":15.27,
|
|
141
|
-
# "view":71.57
|
|
142
|
-
# },
|
|
143
|
-
# "method":"GET",
|
|
144
|
-
# "path":"/api/v2/tickers",
|
|
145
|
-
# "params":{"password":"[FILTERED]","a":"b"},
|
|
146
|
-
# "ip":"127.0.0.1",
|
|
147
|
-
# "ua":"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"
|
|
148
|
-
#}
|
|
149
|
-
formatter = Xyeger::Formatters::Json.new(
|
|
150
|
-
message: ->(message, _context) { "#{message[:method]} #{message[:path]}" },
|
|
151
|
-
context: ->(message, _context) { message }
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
use GrapeLogging::Middleware::RequestLogger,
|
|
155
|
-
logger: logger,
|
|
156
|
-
formatter: formatter,
|
|
157
|
-
include: [
|
|
158
|
-
GrapeLogging::Loggers::Response.new,
|
|
159
|
-
GrapeLogging::Loggers::FilterParameters.new,
|
|
160
|
-
GrapeLogging::Loggers::ClientEnv.new
|
|
161
|
-
]
|
|
162
|
-
end
|
|
206
|
+
logger.formatter = Xyeger::Formatters::Text.new
|
|
207
|
+
```
|
|
163
208
|
```
|
|
209
|
+
[2017-08-03 16:59:51 +0300] [DEBUG] flow_id=6821a053-ad20-4d58-905a-25a923f7a412 With Context
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Custom Formatter
|
|
213
|
+
You are free to implement your own formatters, but things to be mentioned: if you need all default keys accessible inside your formatter, you have to inherit from `Xyeger::Formatters::Base` formatter. See `lib/xyeger/formatters` directory for more info.
|
|
164
214
|
|
|
165
|
-
##
|
|
215
|
+
## Integrations
|
|
216
|
+
You can easily use `Xyeger` with different type of applications and here are some built in integrations
|
|
217
|
+
|
|
218
|
+
### Rails
|
|
219
|
+
Integration with `rails` add `Xyeger::Rails::FlowIdMiddlare` in application middlware stack so it will automatically add end-to-end identifier(`:fid`) inside context for each request and clear it out when request is ended.
|
|
220
|
+
|
|
221
|
+
### Grape
|
|
222
|
+
Grape has it's own logger inside. Most of the time you create extra module to specify logging preferences. It may look something like that.
|
|
166
223
|
|
|
167
224
|
```ruby
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
module API
|
|
226
|
+
module Helpers
|
|
227
|
+
module Logger
|
|
228
|
+
extend ActiveSupport::Concern
|
|
229
|
+
|
|
230
|
+
included do
|
|
231
|
+
logger.extend(Xyeger::Logger)
|
|
232
|
+
logger.formatter = Xyeger.config.formatter
|
|
233
|
+
|
|
234
|
+
use GrapeLogging::Middleware::RequestLogger,
|
|
235
|
+
logger: logger,
|
|
236
|
+
formatter: logger.formatter,
|
|
237
|
+
include: [
|
|
238
|
+
GrapeLogging::Loggers::Response.new,
|
|
239
|
+
GrapeLogging::Loggers::FilterParameters.new,
|
|
240
|
+
GrapeLogging::Loggers::ClientEnv.new
|
|
241
|
+
]
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
170
246
|
```
|
|
171
247
|
|
|
172
|
-
|
|
248
|
+
So inside your application you just include `API::Helpers::Logger`
|
|
173
249
|
|
|
174
250
|
```ruby
|
|
175
|
-
|
|
251
|
+
module API
|
|
252
|
+
class Root < Grape::API
|
|
253
|
+
include API::Helpers::Logger
|
|
254
|
+
end
|
|
255
|
+
end
|
|
176
256
|
```
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
257
|
+
|
|
258
|
+
### Sidekiq
|
|
259
|
+
Sidekiq integration is really useful too. It store `fid` inside job and you can track logs even for retries. You don't have to do anything extra.
|
|
260
|
+
|
|
261
|
+
### Sentry
|
|
262
|
+
Sentry integration is hardcoded inside gem. So when you add anything inside context of Xyeger, it also means that you add something to Sentry context.
|
|
263
|
+
|
|
264
|
+
### Plain ruby app
|
|
265
|
+
For plain ruby application you have implement several steps:
|
|
266
|
+
|
|
267
|
+
```ruby
|
|
268
|
+
# Configure your Xyeger
|
|
269
|
+
Xyeger.configure {}
|
|
270
|
+
|
|
271
|
+
# Create instance of some logger
|
|
272
|
+
logger = Logger.new(STDOUT)
|
|
273
|
+
|
|
274
|
+
# Extend your logger with Xyeger::Logger
|
|
275
|
+
logger.extend(Xyeger::Logger)
|
|
276
|
+
|
|
277
|
+
# You are ready to go
|
|
278
|
+
logger.info('Some message')
|
|
193
279
|
```
|
|
194
280
|
|
|
195
281
|
|
|
282
|
+
|
|
196
283
|
## License
|
|
197
284
|
|
|
198
285
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'xyeger'
|
|
5
5
|
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +10,5 @@ require "xyeger"
|
|
|
10
10
|
# require "pry"
|
|
11
11
|
# Pry.start
|
|
12
12
|
|
|
13
|
-
require
|
|
13
|
+
require 'irb'
|
|
14
14
|
IRB.start(__FILE__)
|
data/lib/xyeger/config.rb
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
module Xyeger
|
|
2
2
|
class Config
|
|
3
|
-
attr_accessor :output,
|
|
4
|
-
|
|
5
|
-
:filter_parameters,
|
|
6
|
-
:filter,
|
|
7
|
-
:hostname,
|
|
8
|
-
:app,
|
|
9
|
-
:env
|
|
3
|
+
attr_accessor :output, :formatter, :hostname, :app, :env, :context_resolver, :message_resolver
|
|
4
|
+
attr_reader :context
|
|
10
5
|
|
|
11
6
|
def initialize
|
|
12
7
|
@output = STDOUT
|
|
13
8
|
@formatter = Xyeger::Formatters::Json.new
|
|
14
|
-
@
|
|
15
|
-
|
|
16
|
-
@
|
|
17
|
-
@
|
|
18
|
-
@
|
|
9
|
+
@hostname = ENV['XYEGER_HOSTNAME'] || ''
|
|
10
|
+
@app = ENV['XYEGER_APPNAME'] || ''
|
|
11
|
+
@env = ENV['XYEGER_ENV'] || ''
|
|
12
|
+
@context = Xyeger::Context
|
|
13
|
+
@context_resolver = Xyeger::ContextResolver
|
|
14
|
+
@message_resolver = Xyeger::MessageResolver
|
|
19
15
|
end
|
|
20
16
|
end
|
|
21
17
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Xyeger
|
|
2
|
+
class Context
|
|
3
|
+
def self.current
|
|
4
|
+
Thread.current[:xyeger_context] ||= {}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.clear_context
|
|
8
|
+
Thread.current[:xyeger_context] = nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.add_context(context = {})
|
|
12
|
+
return unless context
|
|
13
|
+
context = Xyeger.config.context_resolver.call(context)
|
|
14
|
+
::Raven.tags_context(context) if defined?(::Raven)
|
|
15
|
+
Thread.current[:xyeger_context] ||= {}
|
|
16
|
+
Thread.current[:xyeger_context].merge!(context || {})
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -5,23 +5,30 @@ module Xyeger
|
|
|
5
5
|
|
|
6
6
|
UNCOLORIZE_REGEXP = /\e\[([;\d]+)?m/
|
|
7
7
|
|
|
8
|
-
attr_reader :attributes
|
|
8
|
+
attr_reader :attributes
|
|
9
9
|
|
|
10
10
|
def initialize(attributes = {})
|
|
11
11
|
@attributes = attributes
|
|
12
12
|
@tags = []
|
|
13
|
-
@colors = Array.new(9) { Paint.random } if attributes[:colored]
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def call(severity, timestamp, context, message)
|
|
17
|
-
message
|
|
18
|
-
message = uncolorize(message) unless attributes[:colored]
|
|
16
|
+
message = uncolorize(message)
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
result = prepare(severity, timestamp, context, message)
|
|
19
|
+
result[:tags] = current_tags if current_tags.any?
|
|
20
|
+
|
|
21
|
+
if attributes[:except]&.any?
|
|
22
|
+
result.except(*attributes[:except])
|
|
23
|
+
else
|
|
24
|
+
result
|
|
25
|
+
end
|
|
26
|
+
end
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
def prepare(severity, timestamp, context, message)
|
|
29
|
+
{
|
|
23
30
|
hostname: Xyeger.config.hostname,
|
|
24
|
-
pid: $$,
|
|
31
|
+
pid: $$, # rubocop:disable Style/SpecialGlobalVars
|
|
25
32
|
app: Xyeger.config.app,
|
|
26
33
|
env: Xyeger.config.env,
|
|
27
34
|
level: severity,
|
|
@@ -29,39 +36,6 @@ module Xyeger
|
|
|
29
36
|
message: message,
|
|
30
37
|
context: context
|
|
31
38
|
}
|
|
32
|
-
|
|
33
|
-
result[:tags] = current_tags if current_tags.any?
|
|
34
|
-
colored(result) if attributes[:colored]
|
|
35
|
-
|
|
36
|
-
result
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private def prepare(message, context)
|
|
40
|
-
new_message = attributes[:message].call(message, context) if attributes[:message]
|
|
41
|
-
new_context = attributes[:context].call(message, context) if attributes[:context]
|
|
42
|
-
|
|
43
|
-
return [new_message, new_context] if attributes[:message] || attributes[:context]
|
|
44
|
-
|
|
45
|
-
case message
|
|
46
|
-
when LogrageRaw
|
|
47
|
-
['Lograge', message.data]
|
|
48
|
-
when ::StandardError
|
|
49
|
-
['StandardError', { class: message.class.name, error: message.to_s }]
|
|
50
|
-
else
|
|
51
|
-
[message.to_s, context]
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private def colored(result)
|
|
56
|
-
result.each_with_index do |(key, value), index|
|
|
57
|
-
result[key] = Paint[value, colors[index]]
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
private def filter_context(context)
|
|
62
|
-
return context unless Xyeger.config.filter && context.is_a?(Hash)
|
|
63
|
-
|
|
64
|
-
Xyeger.config.filter.filter(context)
|
|
65
39
|
end
|
|
66
40
|
|
|
67
41
|
def uncolorize(message)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Xyeger
|
|
2
|
+
module Formatters
|
|
3
|
+
class Text < Base
|
|
4
|
+
def call(*args)
|
|
5
|
+
result = super(*args)
|
|
6
|
+
arr = []
|
|
7
|
+
arr << "[#{result[:time]}]"
|
|
8
|
+
arr << "[#{result[:level]}]".ljust(8)
|
|
9
|
+
|
|
10
|
+
context = result[:context]
|
|
11
|
+
arr << "[#{context[:fid]}] " if context[:fid]
|
|
12
|
+
|
|
13
|
+
arr << context.except(:fid).map { |k, v| "#{k}=#{v}" }.join(' ')
|
|
14
|
+
arr << result[:message]
|
|
15
|
+
|
|
16
|
+
"#{arr.join(' ').gsub(/ +/, ' ')}\n"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
data/lib/xyeger/formatters.rb
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
autoload :Base
|
|
6
|
-
autoload :Json
|
|
7
|
-
autoload :Values
|
|
8
|
-
autoload :LogrageRaw
|
|
9
|
-
autoload :SidekiqJson
|
|
10
|
-
end
|
|
11
|
-
end
|
|
1
|
+
require 'xyeger/formatters/base'
|
|
2
|
+
require 'xyeger/formatters/json'
|
|
3
|
+
require 'xyeger/formatters/text'
|
|
4
|
+
require 'xyeger/formatters/values'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'rails'
|
|
2
|
+
|
|
3
|
+
module Xyeger
|
|
4
|
+
module Rails
|
|
5
|
+
class FlowIdMiddleware
|
|
6
|
+
def initialize(app)
|
|
7
|
+
@app = app
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
request = ActionDispatch::Request.new(env)
|
|
12
|
+
fid = request.request_id || SecureRandom.uuid
|
|
13
|
+
Xyeger.add_context(fid: fid)
|
|
14
|
+
@app.call(env)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Railtie < ::Rails::Railtie
|
|
20
|
+
initializer 'xyeger.configure_rails_initialization' do |app|
|
|
21
|
+
app.config.middleware.insert_after(
|
|
22
|
+
ActionDispatch::RequestId, Xyeger::Middlewares::ClearContext
|
|
23
|
+
)
|
|
24
|
+
app.config.middleware.insert_after(
|
|
25
|
+
ActionDispatch::RequestId, Xyeger::Rails::FlowIdMiddleware
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
config.after_initialize do
|
|
30
|
+
::Rails.logger = ActiveSupport::Logger.new(STDOUT)
|
|
31
|
+
::Rails.logger.extend(Xyeger::Logger)
|
|
32
|
+
::ActiveSupport.on_load(:action_record) { self.logger = ::Rails.logger }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'sidekiq'
|
|
2
|
+
|
|
3
|
+
module Xyeger
|
|
4
|
+
module Sidekiq
|
|
5
|
+
module LoggingPatch
|
|
6
|
+
def with_job_hash_context(job_hash)
|
|
7
|
+
# If we're using a wrapper class, like ActiveJob, use the 'wrapped'
|
|
8
|
+
# attribute to expose the underlying thing.
|
|
9
|
+
klass = job_hash['wrapped'] || job_hash['class']
|
|
10
|
+
jid = job_hash['jid']
|
|
11
|
+
fid = job_hash['fid'] || Xyeger.context.current[:fid] || SecureRandom.uuid
|
|
12
|
+
|
|
13
|
+
Xyeger.add_context(worker: klass, fid: fid, jid: jid)
|
|
14
|
+
|
|
15
|
+
yield
|
|
16
|
+
ensure
|
|
17
|
+
Xyeger.clear_context
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class FlowIdMiddleware
|
|
22
|
+
def call(_worker_class, msg, _queue, _redis_pool)
|
|
23
|
+
msg['fid'] = Xyeger.context.current[:fid]
|
|
24
|
+
yield
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
::Sidekiq.logger = Rails.logger
|
|
31
|
+
|
|
32
|
+
::Sidekiq::Logging.singleton_class.prepend(Xyeger::Sidekiq::LoggingPatch)
|
|
33
|
+
|
|
34
|
+
::Sidekiq.configure_client do |config|
|
|
35
|
+
config.client_middleware do |chain|
|
|
36
|
+
chain.add(Xyeger::Sidekiq::FlowIdMiddleware)
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/xyeger/logger.rb
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
module Xyeger
|
|
2
2
|
module Logger
|
|
3
3
|
def self.extended(base)
|
|
4
|
-
base.formatter = Xyeger.config.formatter
|
|
4
|
+
base.formatter = Xyeger.config.formatter
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if block
|
|
12
|
-
result = block.call
|
|
7
|
+
def add(severity, message = nil, progname = nil, &block)
|
|
8
|
+
message = prepare(message, progname, &block)
|
|
9
|
+
super(severity, message, Xyeger.context.current)
|
|
10
|
+
end
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
def prepare(message, progname, &block)
|
|
13
|
+
if message.nil?
|
|
14
|
+
if block_given?
|
|
15
|
+
message = yield(block)
|
|
16
|
+
else
|
|
17
|
+
message = progname
|
|
18
|
+
progname = nil
|
|
19
19
|
end
|
|
20
|
-
add(ActiveSupport::Logger::Severity.const_get(severity), message, context)
|
|
21
20
|
end
|
|
21
|
+
Xyeger.config.message_resolver.call(message, progname)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Xyeger
|
|
2
|
+
class MessageResolver
|
|
3
|
+
def self.call(message, progname)
|
|
4
|
+
message =
|
|
5
|
+
case message
|
|
6
|
+
when ::StandardError
|
|
7
|
+
[message.class.name, message].compact.join(' ')
|
|
8
|
+
else
|
|
9
|
+
message.to_s
|
|
10
|
+
end
|
|
11
|
+
[progname, message].compact.join(' ')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/xyeger/version.rb
CHANGED
data/lib/xyeger.rb
CHANGED
|
@@ -1,48 +1,30 @@
|
|
|
1
|
-
require 'active_support/logger'
|
|
2
1
|
require 'active_support/tagged_logging'
|
|
3
|
-
require '
|
|
4
|
-
require 'active_support/ordered_options'
|
|
5
|
-
require 'paint'
|
|
6
|
-
require 'lograge'
|
|
2
|
+
require 'forwardable'
|
|
7
3
|
require 'xyeger/version'
|
|
4
|
+
require 'xyeger/config'
|
|
5
|
+
require 'xyeger/context'
|
|
6
|
+
require 'xyeger/context_resolver'
|
|
7
|
+
require 'xyeger/message_resolver'
|
|
8
|
+
require 'xyeger/formatters'
|
|
9
|
+
require 'xyeger/logger'
|
|
10
|
+
require 'xyeger/middlewares/clear_context'
|
|
11
|
+
require 'xyeger/integrations/rails' if defined?(::Rails)
|
|
12
|
+
require 'xyeger/integrations/sidekiq' if defined?(::Sidekiq)
|
|
8
13
|
|
|
9
14
|
module Xyeger
|
|
10
15
|
module_function
|
|
11
16
|
|
|
12
|
-
extend ActiveSupport::Autoload
|
|
13
|
-
|
|
14
|
-
autoload :Config
|
|
15
|
-
autoload :Logger
|
|
16
|
-
autoload :Formatters
|
|
17
|
-
|
|
18
17
|
class << self
|
|
19
18
|
attr_reader :config
|
|
19
|
+
extend Forwardable
|
|
20
20
|
|
|
21
21
|
def configure
|
|
22
|
-
@config ||= Xyeger::Config.new
|
|
23
|
-
|
|
22
|
+
@config ||= Xyeger::Config.new
|
|
24
23
|
yield(@config)
|
|
25
|
-
|
|
26
|
-
if @config.filter_parameters
|
|
27
|
-
@config.filter ||= ActionDispatch::Http::ParameterFilter.new(@config.filter_parameters)
|
|
28
|
-
end
|
|
29
|
-
Xyeger.setup
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def setup
|
|
34
|
-
app = Rails.application
|
|
35
|
-
setup_lograge(app)
|
|
36
|
-
|
|
37
|
-
Rails.logger.extend(Logger)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def setup_lograge(app)
|
|
41
|
-
app.config.lograge.formatter = -> (data) { Formatters::LogrageRaw.new(data: data) }
|
|
42
|
-
app.config.lograge.custom_options = lambda do |event|
|
|
43
|
-
{ params: event.payload[:params]&.except('controller', 'action', 'format', 'id') }
|
|
44
24
|
end
|
|
45
25
|
|
|
46
|
-
|
|
26
|
+
def_delegator :config, :context
|
|
27
|
+
def_delegator :context, :add_context
|
|
28
|
+
def_delegator :context, :clear_context
|
|
47
29
|
end
|
|
48
30
|
end
|
data/xyeger.gemspec
CHANGED
|
@@ -5,10 +5,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
5
5
|
require 'xyeger/version'
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
|
-
spec.name =
|
|
8
|
+
spec.name = 'xyeger'
|
|
9
9
|
spec.version = Xyeger::VERSION
|
|
10
|
-
spec.authors = [
|
|
11
|
-
spec.email = [
|
|
10
|
+
spec.authors = ['Avramov Vsevolod']
|
|
11
|
+
spec.email = ['vsevolod@cryptopay.me']
|
|
12
12
|
|
|
13
13
|
spec.summary = 'Uniq logger for project'
|
|
14
14
|
spec.description = 'Uniq logger for project'
|
|
@@ -20,26 +20,23 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
if spec.respond_to?(:metadata)
|
|
21
21
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
22
22
|
else
|
|
23
|
-
raise
|
|
24
|
-
|
|
23
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
|
24
|
+
'public gem pushes.'
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
spec.files
|
|
27
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
28
28
|
f.match(%r{^(test|spec|features)/})
|
|
29
29
|
end
|
|
30
|
-
spec.bindir =
|
|
30
|
+
spec.bindir = 'exe'
|
|
31
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
32
|
-
spec.require_paths = [
|
|
33
|
-
|
|
34
|
-
spec.add_dependency 'lograge', '>= 0.4'
|
|
35
|
-
spec.add_dependency 'paint', '~> 2.0'
|
|
32
|
+
spec.require_paths = ['lib']
|
|
36
33
|
|
|
37
34
|
spec.add_runtime_dependency 'activesupport', '>= 4'
|
|
38
35
|
spec.add_runtime_dependency 'actionpack', '>= 4'
|
|
39
36
|
spec.add_runtime_dependency 'railties', '>= 4'
|
|
40
37
|
|
|
41
|
-
spec.add_development_dependency
|
|
42
|
-
spec.add_development_dependency
|
|
43
|
-
spec.add_development_dependency
|
|
38
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
|
39
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
40
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
44
41
|
spec.add_development_dependency 'rubocop'
|
|
45
42
|
end
|
metadata
CHANGED
|
@@ -1,43 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xyeger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0.rc
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Avramov Vsevolod
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-08-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: lograge
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0.4'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - ">="
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0.4'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: paint
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '2.0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '2.0'
|
|
41
13
|
- !ruby/object:Gem::Dependency
|
|
42
14
|
name: activesupport
|
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -144,8 +116,9 @@ extensions: []
|
|
|
144
116
|
extra_rdoc_files: []
|
|
145
117
|
files:
|
|
146
118
|
- ".gitignore"
|
|
147
|
-
-
|
|
119
|
+
- ".rubocop.yml"
|
|
148
120
|
- Gemfile
|
|
121
|
+
- Gemfile.lock
|
|
149
122
|
- LICENSE.txt
|
|
150
123
|
- README.md
|
|
151
124
|
- Rakefile
|
|
@@ -153,14 +126,18 @@ files:
|
|
|
153
126
|
- bin/setup
|
|
154
127
|
- lib/xyeger.rb
|
|
155
128
|
- lib/xyeger/config.rb
|
|
129
|
+
- lib/xyeger/context.rb
|
|
130
|
+
- lib/xyeger/context_resolver.rb
|
|
156
131
|
- lib/xyeger/formatters.rb
|
|
157
132
|
- lib/xyeger/formatters/base.rb
|
|
158
133
|
- lib/xyeger/formatters/json.rb
|
|
159
|
-
- lib/xyeger/formatters/
|
|
160
|
-
- lib/xyeger/formatters/lograge_raw.rb
|
|
161
|
-
- lib/xyeger/formatters/sidekiq_json.rb
|
|
134
|
+
- lib/xyeger/formatters/text.rb
|
|
162
135
|
- lib/xyeger/formatters/values.rb
|
|
136
|
+
- lib/xyeger/integrations/rails.rb
|
|
137
|
+
- lib/xyeger/integrations/sidekiq.rb
|
|
163
138
|
- lib/xyeger/logger.rb
|
|
139
|
+
- lib/xyeger/message_resolver.rb
|
|
140
|
+
- lib/xyeger/middlewares/clear_context.rb
|
|
164
141
|
- lib/xyeger/version.rb
|
|
165
142
|
- xyeger.gemspec
|
|
166
143
|
homepage: https://github.com/vsevolod/xyeger
|
|
@@ -179,12 +156,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
179
156
|
version: '0'
|
|
180
157
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
158
|
requirements:
|
|
182
|
-
- - "
|
|
159
|
+
- - ">"
|
|
183
160
|
- !ruby/object:Gem::Version
|
|
184
|
-
version:
|
|
161
|
+
version: 1.3.1
|
|
185
162
|
requirements: []
|
|
186
163
|
rubyforge_project:
|
|
187
|
-
rubygems_version: 2.6.
|
|
164
|
+
rubygems_version: 2.6.10
|
|
188
165
|
signing_key:
|
|
189
166
|
specification_version: 4
|
|
190
167
|
summary: Uniq logger for project
|
data/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Contributor Covenant Code of Conduct
|
|
2
|
-
|
|
3
|
-
## Our Pledge
|
|
4
|
-
|
|
5
|
-
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
-
contributors and maintainers pledge to making participation in our project and
|
|
7
|
-
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
-
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
-
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
-
orientation.
|
|
11
|
-
|
|
12
|
-
## Our Standards
|
|
13
|
-
|
|
14
|
-
Examples of behavior that contributes to creating a positive environment
|
|
15
|
-
include:
|
|
16
|
-
|
|
17
|
-
* Using welcoming and inclusive language
|
|
18
|
-
* Being respectful of differing viewpoints and experiences
|
|
19
|
-
* Gracefully accepting constructive criticism
|
|
20
|
-
* Focusing on what is best for the community
|
|
21
|
-
* Showing empathy towards other community members
|
|
22
|
-
|
|
23
|
-
Examples of unacceptable behavior by participants include:
|
|
24
|
-
|
|
25
|
-
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
-
advances
|
|
27
|
-
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
-
* Public or private harassment
|
|
29
|
-
* Publishing others' private information, such as a physical or electronic
|
|
30
|
-
address, without explicit permission
|
|
31
|
-
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
-
professional setting
|
|
33
|
-
|
|
34
|
-
## Our Responsibilities
|
|
35
|
-
|
|
36
|
-
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
-
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
-
response to any instances of unacceptable behavior.
|
|
39
|
-
|
|
40
|
-
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
-
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
-
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
-
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
-
threatening, offensive, or harmful.
|
|
45
|
-
|
|
46
|
-
## Scope
|
|
47
|
-
|
|
48
|
-
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
-
when an individual is representing the project or its community. Examples of
|
|
50
|
-
representing a project or community include using an official project e-mail
|
|
51
|
-
address, posting via an official social media account, or acting as an appointed
|
|
52
|
-
representative at an online or offline event. Representation of a project may be
|
|
53
|
-
further defined and clarified by project maintainers.
|
|
54
|
-
|
|
55
|
-
## Enforcement
|
|
56
|
-
|
|
57
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
-
reported by contacting the project team at vsevolod@cryptopay.me. All
|
|
59
|
-
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
-
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
-
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
-
Further details of specific enforcement policies may be posted separately.
|
|
63
|
-
|
|
64
|
-
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
-
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
-
members of the project's leadership.
|
|
67
|
-
|
|
68
|
-
## Attribution
|
|
69
|
-
|
|
70
|
-
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
-
available at [http://contributor-covenant.org/version/1/4][version]
|
|
72
|
-
|
|
73
|
-
[homepage]: http://contributor-covenant.org
|
|
74
|
-
[version]: http://contributor-covenant.org/version/1/4/
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
module Xyeger
|
|
2
|
-
module Formatters
|
|
3
|
-
class SidekiqJson < Base
|
|
4
|
-
def call(severity, timestamp, context, message)
|
|
5
|
-
context, message = prepare_message(message) unless context
|
|
6
|
-
|
|
7
|
-
super(severity, timestamp, context, message).merge(
|
|
8
|
-
tid: "TID-#{Thread.current.object_id.to_s(36)}",
|
|
9
|
-
sidekiq_context: sidekiq_context
|
|
10
|
-
).to_json + "\n"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def sidekiq_context
|
|
14
|
-
c = Thread.current[:sidekiq_context]
|
|
15
|
-
c.join(' ') if c&.any?
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def prepare_message(message)
|
|
19
|
-
json = JSON.parse(message)
|
|
20
|
-
[filter_context(json), 'Sidekiq']
|
|
21
|
-
rescue JSON::ParserError => e
|
|
22
|
-
[nil, message]
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|