production_log_analyzer 1.3.0 → 1.5.0

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.
data/test/test_parser.rb CHANGED
@@ -10,8 +10,8 @@ require 'production_log/parser'
10
10
 
11
11
  class TestLogEntry < Test::Unit::TestCase
12
12
 
13
- def setup
14
- @entry = LogParser::LogEntry.new <<EOF
13
+ def setup
14
+ @entry = LogParser::LogEntry.new <<EOF
15
15
  Processing TwinklerController#index (for 81.109.96.173 at Wed Dec 01 16:01:56 CST 2004)
16
16
  Parameters: {\"action\"=>\"index\", \"controller\"=>\"twinkler\"}
17
17
  Browser Load First (0.001114) SELECT * FROM browsers WHERE ubid = 'ixsXHgUo7U9PJGgBzr7e9ocaDOc=' LIMIT 1
@@ -20,10 +20,10 @@ Rendering twinkler/index within layouts/default
20
20
  Rendering layouts/default (200 OK)
21
21
  Completed in 0.616122 (1 reqs/sec) | Rendering: 0.242475 (39%) | DB: 0.002876 (0%)
22
22
  EOF
23
- end
23
+ end
24
24
 
25
- def test_parse
26
- request = <<EOF
25
+ def test_parse
26
+ request = <<EOF
27
27
  Processing RssController#uber (for 67.18.200.5 at Mon Mar 07 00:00:25 CST 2005)
28
28
  Parameters: {:id=>"author", :"rss/uber/author.html/uber/author"=>nil, :action=>"uber", :username=>"looch", :controller=>"rss"}
29
29
  Cookie set: auth=dc%2FGUP20BwziF%2BApGecc0pXB0PF0obi55az63ubAFtsnOOdJPkhfJH2U09yuzQD3WtdmWnydLzFcRA78kwi7Gw%3D%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
@@ -34,65 +34,65 @@ ProfileImage Load (0.001554) SELECT * FROM profile_images WHERE id = 2782 LIMI
34
34
  Rendering rss/rss2.0 (200 OK)
35
35
  Completed in 0.034519 (28 reqs/sec) | Rendering: 0.011770 (34%) | DB: 0.007962 (23%)
36
36
  EOF
37
- request = request.split "\n"
38
-
39
- entry = LogParser::LogEntry.new []
40
-
41
- entry.parse request
42
- assert_kind_of LogParser::LogEntry, entry
43
- assert_equal "RssController#uber", entry.page
44
- assert_equal 3, entry.queries.length
45
- assert_equal ['Browser Load', 0.003963], entry.queries.first
46
- assert_equal 0.034519, entry.request_time
47
- end
37
+ request = request.split "\n"
48
38
 
49
- def test_page
50
- assert_equal "TwinklerController#index", @entry.page
51
- end
39
+ entry = LogParser::LogEntry.new []
52
40
 
53
- def test_ip
54
- assert_equal "81.109.96.173", @entry.ip
55
- end
41
+ entry.parse request
42
+ assert_kind_of LogParser::LogEntry, entry
43
+ assert_equal "RssController#uber", entry.page
44
+ assert_equal 3, entry.queries.length
45
+ assert_equal ['Browser Load', 0.003963], entry.queries.first
46
+ assert_equal 0.034519, entry.request_time
47
+ end
56
48
 
57
- def test_time
58
- assert_equal "Wed Dec 01 16:01:56 CST 2004", @entry.time
59
- end
49
+ def test_page
50
+ assert_equal "TwinklerController#index", @entry.page
51
+ end
60
52
 
61
- def test_queries
62
- expected = []
63
- expected << ["Browser Load First", 0.001114]
64
- expected << ["Goal Count", 0.001762]
65
- assert_equal expected, @entry.queries
66
- end
53
+ def test_ip
54
+ assert_equal "81.109.96.173", @entry.ip
55
+ end
56
+
57
+ def test_time
58
+ assert_equal "Wed Dec 01 16:01:56 CST 2004", @entry.time
59
+ end
67
60
 
68
- def test_request_time
69
- assert_equal 0.616122, @entry.request_time
61
+ def test_queries
62
+ expected = []
63
+ expected << ["Browser Load First", 0.001114]
64
+ expected << ["Goal Count", 0.001762]
65
+ assert_equal expected, @entry.queries
66
+ end
70
67
 
71
- @entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
68
+ def test_request_time
69
+ assert_equal 0.616122, @entry.request_time
70
+
71
+ @entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
72
72
  Completed in 0.261485 (3 reqs/sec) | DB: 0.009325 (3%)"
73
73
 
74
- assert_equal 0.261485, @entry.request_time
75
- end
74
+ assert_equal 0.261485, @entry.request_time
75
+ end
76
76
 
77
- def test_render_time
78
- assert_equal 0.242475, @entry.render_time
77
+ def test_render_time
78
+ assert_equal 0.242475, @entry.render_time
79
79
 
80
- @entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
80
+ @entry = LogParser::LogEntry.new "Processing TwinklerController#add_thing (for 144.164.232.114 at Wed Dec 01 16:01:56 CST 2004)
81
81
  Completed in 0.261485 (3 reqs/sec) | DB: 0.009325 (3%)"
82
82
 
83
- assert_equal 0, @entry.render_time
84
- end
83
+ assert_equal 0, @entry.render_time
84
+ end
85
85
 
86
- def test_db_time
87
- assert_equal 0.002876, @entry.db_time
88
- end
86
+ def test_db_time
87
+ assert_equal 0.002876, @entry.db_time
88
+ end
89
89
 
90
90
  end
91
91
 
92
- class TestLogParser <Test::Unit::TestCase
92
+ class TestLogParser < Test::Unit::TestCase
93
93
 
94
- def test_class_parse
95
- log = StringIO.new <<-EOF
94
+ def test_class_parse
95
+ log = StringIO.new <<-EOF
96
96
  Mar 7 00:00:25 online1 rails[59628]: Processing RssController#uber (for 67.18.200.5 at Mon Mar 07 00:00:25 CST 2005)
97
97
  Mar 7 00:00:25 online1 rails[59628]: Parameters: {:id=>"author", :"rss/uber/author.html/uber/author"=>nil, :action=>"uber", :username=>"looch", :controller=>"rss"}
98
98
  Mar 7 00:00:25 online1 rails[59628]: Cookie set: auth=dc%2FGUP20BwziF%2BApGecc0pXB0PF0obi55az63ubAFtsnOOdJPkhfJH2U09yuzQD3WtdmWnydLzFcRA78kwi7Gw%3D%3D; path=/; expires=Thu, 05 Mar 2015 06:00:25 GMT
@@ -104,18 +104,18 @@ Mar 7 00:00:25 online1 rails[59628]: Rendering rss/rss2.0 (200 OK)
104
104
  Mar 7 00:00:25 online1 rails[59628]: Completed in 0.034519 (28 reqs/sec) | Rendering: 0.011770 (34%) | DB: 0.007962 (23%)
105
105
  EOF
106
106
 
107
- entries = []
107
+ entries = []
108
108
 
109
- LogParser.parse log do |entry|
110
- entries << entry
111
- end
112
-
113
- assert_equal 1, entries.length
114
- assert_equal 'RssController#uber', entries.first.page
109
+ LogParser.parse log do |entry|
110
+ entries << entry
115
111
  end
116
112
 
117
- def test_class_parse_components
118
- log = StringIO.new <<-EOF
113
+ assert_equal 1, entries.length
114
+ assert_equal 'RssController#uber', entries.first.page
115
+ end
116
+
117
+ def test_class_parse_components
118
+ log = StringIO.new <<-EOF
119
119
  Jul 11 10:05:20 www rails[61243]: Processing ChatroomsController#launch (for 213.152.37.169 at Mon Jul 11 10:05:20 CDT 2005)
120
120
  Jul 11 10:05:20 www rails[61243]: Start rendering component ({:action=>"online_count", :controller=>"members"}):
121
121
  Jul 11 10:05:20 www rails[34216]: Processing ChatroomsController#launch (for 213.152.37.169 at Mon Jul 11 10:05:20 CDT 2005)
@@ -136,44 +136,118 @@ Jul 11 10:05:20 www rails[61243]: End of component rendering
136
136
  Jul 11 10:05:28 www rails[61243]: Completed in 8.65005 (0 reqs/sec) | Rendering: 8.64820 (99%) | DB: 0.00000 (0%)
137
137
  EOF
138
138
 
139
- entries = []
140
- LogParser.parse(log) { |entry| entries << entry }
141
-
142
- assert_equal 3, entries.length
143
- assert_equal 'ChatroomsController#launch', entries.first.page
144
- assert_equal 8.65005, entries.first.request_time
139
+ entries = []
140
+ LogParser.parse(log) { |entry| entries << entry }
141
+
142
+ assert_equal 3, entries.length
143
+ assert_equal 'ChatroomsController#launch', entries.first.page
144
+ assert_equal 8.65005, entries.first.request_time
145
+ end
146
+
147
+ def test_class_parse_entries_with_pre_processing_garbage
148
+ log = StringIO.new <<-EOF
149
+ Jan 03 12:51:34 duo2 rails[4347]: Font Load (0.000475) SELECT * FROM fonts ORDER BY name 
150
+ Jan 03 12:51:34 duo2 rails[4347]: Processing StylesheetsController#show (for 127.0.0.1 at 2007-01-03 12:51:34) [GET]
151
+ Jan 03 12:51:34 duo2 rails[4347]: Parameters: {"action"=>"show", "id"=>"1", "controller"=>"stylesheets"}
152
+ Jan 03 12:51:34 duo2 rails[4347]: Newspaper Load (0.000970) SELECT newspapers.* FROM newspapers INNER JOIN users ON newspapers.editor_in_chief = users.id WHERE (users.login = 'geoff') LIMIT 1
153
+ Jan 03 12:51:34 duo2 rails[4347]: Layout Load (0.000501) SELECT * FROM layouts WHERE (layouts.id = 1) LIMIT 1
154
+ Jan 03 12:51:34 duo2 rails[4347]: Completed in 0.00807 (123 reqs/sec) | Rendering: 0.00006 (0%) | DB: 0.00195 (24%) | 200 OK [http://geoff.localhost.com/stylesheets/show/1/styles.css]
155
+ EOF
156
+
157
+ entries = []
158
+ LogParser.parse(log) { |entry| entries << entry }
159
+
160
+ assert_equal 1, entries.length, "Number of entries was incorrect"
161
+ assert_equal 'StylesheetsController#show', entries.first.page
162
+ assert_equal 0.00807, entries.first.request_time
163
+ end
164
+
165
+ def test_class_parse_rails_engines_plugin
166
+ log = StringIO.new <<-EOF
167
+ Jan 03 12:24:21 duo2 rails[4277]: Trying to start engine 'login_engine' from '/Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine'
168
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/lib/login_engine to the load path
169
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/views/user_notify to the load path
170
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/views/user to the load path
171
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/views to the load path
172
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/models to the load path
173
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/helpers to the load path
174
+ Jan 03 12:24:21 duo2 rails[4277]: adding /Users/topfunky/web/rails/repos/roughunderbelly/vendor/plugins/login_engine/app/controllers to the load path
175
+ Jan 03 12:24:21 duo2 rails[4277]: Attempting to copy public engine files from '/Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/public'
176
+ Jan 03 12:24:21 duo2 rails[4277]: source dirs: ["/Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/public/stylesheets"]
177
+ Jan 03 12:24:22 duo2 rails[4277]: finally loading from application: 'exception_notifier.rb'
178
+ Jan 03 12:24:22 duo2 rails[4277]: requiring file 'exception_notifier_helper'
179
+ Jan 03 12:24:22 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/exception_notifier_helper.rb
180
+ Jan 03 12:24:22 duo2 rails[4277]: finally loading from application: 'exception_notifier_helper.rb'
181
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: '/Users/topfunky/web/rails/repos/roughunderbelly/config/../app/controllers/application.rb'
182
+ Jan 03 12:24:23 duo2 rails[4277]: requiring file 'application_helper'
183
+ Jan 03 12:24:23 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/application_helper.rb
184
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'application_helper.rb'
185
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'exception_notifiable.rb'
186
+ Jan 03 12:24:23 duo2 rails[4277]: requiring file 'user_helper'
187
+ Jan 03 12:24:23 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/user_helper.rb
188
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'user_helper.rb'
189
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'user.rb'
190
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'task.rb'
191
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'client.rb'
192
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'email.rb'
193
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'worth.rb'
194
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'column_pref.rb'
195
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'timer.rb'
196
+ Jan 03 12:24:23 duo2 rails[4277]: requiring file '/Users/topfunky/web/rails/repos/roughunderbelly/config/../app/controllers/tasks_controller.rb'
197
+ Jan 03 12:24:23 duo2 rails[4277]: detected RAILS_ROOT, rewriting to 'app/controllers/tasks_controller.rb'
198
+ Jan 03 12:24:23 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/app/controllers/tasks_controller.rb
199
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: '/Users/topfunky/web/rails/repos/roughunderbelly/config/../app/controllers/tasks_controller.rb'
200
+ Jan 03 12:24:23 duo2 rails[4277]: requiring file 'tasks_helper'
201
+ Jan 03 12:24:23 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/tasks_helper.rb
202
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'tasks_helper.rb'
203
+ Jan 03 12:24:23 duo2 rails[4277]: requiring file 'sparklines_helper'
204
+ Jan 03 12:24:23 duo2 rails[4277]: checking 'login_engine' for /Users/topfunky/web/rails/repos/roughunderbelly/config/../vendor/plugins/login_engine/sparklines_helper.rb
205
+ Jan 03 12:24:23 duo2 rails[4277]: finally loading from application: 'sparklines_helper.rb'
206
+ Jan 03 12:24:24 duo2 rails[4277]: SQL (0.000072) BEGIN
207
+ Jan 03 12:24:24 duo2 rails[4277]: SQL (0.000240) INSERT INTO sessions (`updated_at`, `session_id`, `data`) VALUES('2007-01-03 20:24:24', 'bdbb75323d5da69f707d5576e907706e', 'BAh7AA==\n')
208
+ Jan 03 12:24:24 duo2 rails[4277]: SQL (0.000400) COMMIT
209
+ Jan 03 12:24:24 duo2 rails[4277]: Processing TasksController#index (for 127.0.0.1 at 2007-01-03 12:24:24) [GET]
210
+ Jan 03 12:24:24 duo2 rails[4277]: Parameters: {"action"=>"index", "controller"=>"tasks"}
211
+ Jan 03 12:24:24 duo2 rails[4277]: Redirected to http://localhost:3000/tasks/list
212
+ Jan 03 12:24:24 duo2 rails[4277]: Completed in 0.00112 (896 reqs/sec) | DB: 0.00071 (63%) | 302 Found [http://localhost/]
213
+ EOF
214
+
215
+ entries = []
216
+ LogParser.parse(log) { |entry| entries << entry }
217
+
218
+ assert_equal 1, entries.length, "The number of entries was incorrect"
219
+ assert_equal 'TasksController#index', entries.first.page
220
+ assert_equal 0.00112, entries.first.request_time
221
+ end
222
+
223
+ def test_class_parse_multi
224
+ entries = []
225
+ File.open 'test/test.syslog.log' do |fp|
226
+ LogParser.parse fp do |entry|
227
+ entries << entry
228
+ end
145
229
  end
146
230
 
147
- def test_class_parse_multi
148
- entries = []
149
- File.open 'test/test.syslog.log' do |fp|
150
- LogParser.parse fp do |entry|
151
- entries << entry
152
- end
153
- end
154
-
155
- assert_equal 11, entries.length
156
- assert_equal 'RssController#uber', entries.first.page
231
+ assert_equal 12, entries.length
232
+ assert_equal 'RssController#uber', entries.first.page
157
233
 
158
- redirect = entries[5]
159
- assert_equal 'TeamsController#progress', redirect.page
160
- assert_equal 0, redirect.render_time
234
+ redirect = entries[5]
235
+ assert_equal 'TeamsController#progress', redirect.page
236
+ assert_equal 0, redirect.render_time
161
237
 
162
- last = entries.last
163
- assert_equal 'PeopleController#progress', last.page
164
- assert_equal 0, last.request_time
165
- end
238
+ last = entries.last
239
+ assert_equal 'PeopleController#progress', last.page
240
+ assert_equal 0, last.request_time
241
+ end
166
242
 
167
- def test_class_parse_0_14_x
168
- entries = []
169
- File.open 'test/test.syslog.0.14.x.log' do |fp|
170
- LogParser.parse fp do |entry|
171
- entries << entry
172
- end
173
- end
243
+ def test_class_parse_0_14_x
244
+ entries = []
245
+ File.open 'test/test.syslog.0.14.x.log' do |fp|
246
+ LogParser.parse fp do |entry|
247
+ entries << entry
248
+ end
174
249
  end
250
+ end
175
251
 
176
252
  end
177
253
 
178
- # vim: ts=4 sts=4 sw=4
179
-
metadata CHANGED
@@ -1,64 +1,84 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: production_log_analyzer
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.3.0
7
- date: 2005-11-08 00:00:00 -08:00
8
- summary: Extracts statistics from Rails production logs
6
+ version: 1.5.0
7
+ date: 2007-05-16 00:00:00 -07:00
8
+ summary: production_log_analyzer lets you find out which actions on a Rails site are slowing you down.
9
9
  require_paths:
10
- - lib
11
- email: hodel@robotcoop.com
12
- homepage:
13
- rubyforge_project:
14
- description:
10
+ - lib
11
+ email: drbrain@segment7.net
12
+ homepage: http://seattlerb.rubyforge.org/production_log_analyzer
13
+ rubyforge_project: seattlerb
14
+ description: production_log_analyzer provides three tools to analyze log files created by SyslogLogger. pl_analyze for getting daily reports, action_grep for pulling log lines for a single action and action_errors to summarize errors with counts.
15
15
  autorequire:
16
- default_executable: pl_analyze
16
+ default_executable:
17
17
  bindir: bin
18
18
  has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
- -
22
- - ">"
23
- - !ruby/object:Gem::Version
24
- version: 0.0.0
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
25
24
  version:
26
25
  platform: ruby
27
26
  signing_key:
28
27
  cert_chain:
28
+ post_install_message:
29
29
  authors:
30
- - Eric Hodel
30
+ - Eric Hodel
31
31
  files:
32
- - Rakefile
33
- - README
34
- - LICENSE
35
- - Manifest.txt
36
- - bin/action_grep
37
- - bin/pl_analyze
38
- - lib/production_log/action_grep.rb
39
- - lib/production_log/analyzer.rb
40
- - lib/production_log/parser.rb
41
- - test/test.syslog.0.14.x.log
42
- - test/test.syslog.log
43
- - test/test_action_grep.rb
44
- - test/test_analyzer.rb
45
- - test/test_parser.rb
46
- test_files: []
32
+ - History.txt
33
+ - LICENSE.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ - Rakefile
37
+ - bin/action_errors
38
+ - bin/action_grep
39
+ - bin/pl_analyze
40
+ - lib/production_log/action_grep.rb
41
+ - lib/production_log/analyzer.rb
42
+ - lib/production_log/parser.rb
43
+ - test/test.syslog.0.14.x.log
44
+ - test/test.syslog.1.2.shortname.log
45
+ - test/test.syslog.empty.log
46
+ - test/test.syslog.log
47
+ - test/test_action_grep.rb
48
+ - test/test_analyzer.rb
49
+ - test/test_parser.rb
50
+ test_files:
51
+ - test/test_action_grep.rb
52
+ - test/test_analyzer.rb
53
+ - test/test_parser.rb
47
54
  rdoc_options: []
55
+
48
56
  extra_rdoc_files: []
57
+
49
58
  executables:
50
- - pl_analyze
51
- - action_grep
59
+ - action_errors
60
+ - action_grep
61
+ - pl_analyze
52
62
  extensions: []
63
+
53
64
  requirements: []
65
+
54
66
  dependencies:
55
- - !ruby/object:Gem::Dependency
56
- name: rails_analyzer_tools
57
- version_requirement:
58
- version_requirements: !ruby/object:Gem::Version::Requirement
59
- requirements:
60
- -
61
- - ">="
62
- - !ruby/object:Gem::Version
63
- version: 1.1.0
64
- version:
67
+ - !ruby/object:Gem::Dependency
68
+ name: rails_analyzer_tools
69
+ version_requirement:
70
+ version_requirements: !ruby/object:Gem::Version::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.4.0
75
+ version:
76
+ - !ruby/object:Gem::Dependency
77
+ name: hoe
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Version::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.2.0
84
+ version: