logplex 0.0.1.pre.4 → 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc2d2954418c3b93be55493748e2561c4b7b4b27
4
+ data.tar.gz: c5fb17e4a46500eb26779b3089b7aeb357e60498
5
+ SHA512:
6
+ metadata.gz: 35fd6b2c2f5e56e6ed6d2036ae5add5e487f25418a552fdce091c02d2a6ecc5e6693a43a44cfc3dc2a24f4eb75728d3cea58865750a2a141f24e711c338a1f18
7
+ data.tar.gz: dd7b526faa13b42dd98261bdc7d3bd64c9389e734a7fcdfc106740b03ecaba58f896665e901d003276cdbfc116dddae24537c6cb26616b1493d985414f050422
data/.gitignore CHANGED
@@ -1,13 +1,14 @@
1
- *.gem
2
- *.rbc
1
+ _yardoc
3
2
  .bundle
4
3
  .config
4
+ .ruby-version
5
5
  .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
6
+ *.gem
7
+ *.rbc
9
8
  coverage
10
9
  doc/
10
+ Gemfile.lock
11
+ InstalledFiles
11
12
  lib/bundler/man
12
13
  pkg
13
14
  rdoc
@@ -15,3 +16,4 @@ spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
17
18
  tmp
19
+ .tags
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.3.1
5
+ script: bundle exec rspec
data/README.md CHANGED
@@ -8,7 +8,7 @@ Logplex is the Heroku log router, and can be found
8
8
  ### Publishing messages
9
9
 
10
10
  ```ruby
11
- publisher = Logplex::Publisher.new(logplex_token, logplex_url)
11
+ publisher = Logplex::Publisher.new(logplex_url)
12
12
  publisher.publish("There's a lady who's sure, all that glitters is gold",
13
13
  process: 'worker.2', host: 'some-host')
14
14
  ```
@@ -31,7 +31,8 @@ eg: [log2viz](https://blog.heroku.com/archives/2013/3/19/log2viz)
31
31
  publisher.publish { vocals: 'Robert Plant', guitar: 'Jimmy Page' }
32
32
  # produces the message: vocals='Robert Plant' guitar='Jimmy Page'
33
33
  ```
34
- ### Consumnig messages
34
+
35
+ ### Consuming messages
35
36
 
36
37
  TBD
37
38
 
@@ -41,7 +42,7 @@ You can configure default values for logplex message posting:
41
42
 
42
43
  ```ruby
43
44
  Logplex.configure do |config|
44
- config.logplex_url = 'https://logplex.example.com'
45
+ config.logplex_url = 'https://logplex.example.com/logs'
45
46
  config.process = 'stats'
46
47
  config.host = 'host'
47
48
  config.publish_timeout = 2
@@ -52,7 +53,7 @@ In the example above, it is now not not necessary to specify a logplex URL,
52
53
  process or host when getting a hold of a publisher and publishing messages:
53
54
 
54
55
  ```ruby
55
- publisher = Logplex::Publisher.new(logplex_token)
56
+ publisher = Logplex::Publisher.new
56
57
  publisher.publish "And she's buying a stairway to heaven"
57
58
  ```
58
59
 
@@ -1,14 +1,16 @@
1
1
  module Logplex
2
2
  class Configuration
3
3
  attr_accessor :logplex_url,
4
+ :app_name,
4
5
  :process,
5
6
  :host,
6
7
  :publish_timeout
7
8
 
8
9
  def initialize
9
- @logplex_url = 'https://east.logplex.io'
10
+ @logplex_url = 'https://east.logplex.io/logs'
10
11
  @host = 'localhost'
11
12
  @publish_timeout = 1
13
+ @app_name = 'app'
12
14
  end
13
15
  end
14
16
 
@@ -20,5 +22,4 @@ module Logplex
20
22
  self.configuration ||= Configuration.new
21
23
  yield(configuration)
22
24
  end
23
-
24
25
  end
@@ -13,8 +13,8 @@ module Logplex
13
13
  FIELD_DISABLED = '-'.freeze
14
14
 
15
15
  def initialize(message, opts = {})
16
- @message = message
17
- @token = opts.fetch(:token)
16
+ @message = message
17
+ @app_name = opts[:app_name] || Logplex.configuration.app_name
18
18
  @time = opts[:time] || DateTime.now
19
19
  @process = opts[:process] || Logplex.configuration.process
20
20
  @host = opts[:host] || Logplex.configuration.host
@@ -22,7 +22,7 @@ module Logplex
22
22
  end
23
23
 
24
24
  def syslog_frame
25
- temp = "#{FACILITY_AND_PRIORITY} #{formatted_time} #{@host} #{@token} #{@process} #{@message_id} #{FIELD_DISABLED} #{formatted_message}"
25
+ temp = "#{FACILITY_AND_PRIORITY} #{formatted_time} #{@host} #{@app_name} #{@process} #{@message_id} #{FIELD_DISABLED} #{formatted_message}"
26
26
  length = temp.length
27
27
  "#{length} #{temp}"
28
28
  end
@@ -34,7 +34,8 @@ module Logplex
34
34
  errors.add(:host, "can't be nil") if @host.nil?
35
35
  end
36
36
 
37
- private
37
+ private
38
+
38
39
  def formatted_time
39
40
  case @time.class
40
41
  when String
@@ -45,7 +46,7 @@ module Logplex
45
46
  end
46
47
 
47
48
  def formatted_message
48
- if @message.kind_of?(Hash)
49
+ if @message.is_a?(Hash)
49
50
  @message.inject([]) do |res, (key, value)|
50
51
  res << %{#{key}="#{value}"}
51
52
  end.join(' ')
@@ -53,6 +54,5 @@ module Logplex
53
54
  @message
54
55
  end
55
56
  end
56
-
57
57
  end
58
58
  end
@@ -1,18 +1,17 @@
1
1
  # encoding: UTF-8
2
- require 'base64'
3
- require 'restclient'
2
+ require 'excon'
4
3
  require 'logplex/message'
5
4
  require 'timeout'
6
5
 
7
6
  module Logplex
8
7
  class Publisher
9
- PUBLISH_ERRORS = [RestClient::InternalServerError,
10
- RestClient::Unauthorized,
8
+ PUBLISH_ERRORS = [Excon::Errors::InternalServerError,
9
+ Excon::Errors::Unauthorized,
11
10
  Timeout::Error].freeze
12
11
 
13
- def initialize(token, logplex_url=nil)
14
- @token = token
12
+ def initialize(logplex_url = nil)
15
13
  @logplex_url = logplex_url || Logplex.configuration.logplex_url
14
+ @token = URI(@logplex_url).password || Logplex.configuration.app_name
16
15
  end
17
16
 
18
17
  def publish(messages, opts={})
@@ -20,11 +19,11 @@ module Logplex
20
19
  unless messages.is_a? Array
21
20
  message_list = [message_list]
22
21
  end
23
- message_list.map! { |m| Message.new(m, opts.merge(token: @token)) }
22
+ message_list.map! { |m| Message.new(m, opts.merge(app_name: @token)) }
24
23
  message_list.each(&:validate)
25
24
  if message_list.inject(true) { |accum, m| m.valid? }
26
25
  begin
27
- Timeout::timeout(Logplex.configuration.publish_timeout) do
26
+ Timeout.timeout(Logplex.configuration.publish_timeout) do
28
27
  api_post(message_list.map(&:syslog_frame).join(''))
29
28
  true
30
29
  end
@@ -34,14 +33,13 @@ module Logplex
34
33
  end
35
34
  end
36
35
 
37
- private
36
+ private
37
+
38
38
  def api_post(message)
39
- auth_token = Base64.encode64("token:#{@token}")
40
- auth = "Basic #{auth_token}"
41
- RestClient.post("#{@logplex_url}/logs", message,
42
- content_type: 'application/logplex-1',
43
- content_length: message.length,
44
- authorization: auth)
39
+ Excon.post(@logplex_url, body: message, headers: {
40
+ "Content-Type" => 'application/logplex-1',
41
+ "Content-Length" => message.length,
42
+ }, expects: [200, 204])
45
43
  end
46
44
  end
47
45
  end
@@ -1,3 +1,3 @@
1
1
  module Logplex
2
- VERSION = "0.0.1.pre.4"
2
+ VERSION = "0.0.1".freeze
3
3
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Logplex::VERSION
9
9
  gem.authors = ["Harold Giménez"]
10
10
  gem.email = ["harold.gimenez@gmail.com"]
11
- gem.description = %q{Publish and Consume Logplex messages}
12
- gem.summary = %q{Publish and Consume Logplex messages}
11
+ gem.description = "Publish and Consume Logplex messages"
12
+ gem.summary = "Publish and Consume Logplex messages"
13
13
  gem.homepage = "https://practiceovertheory.com"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -17,7 +17,6 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
  gem.add_dependency "valcro"
20
- gem.add_dependency "rest-client"
20
+ gem.add_dependency "excon"
21
21
  gem.add_development_dependency "rspec"
22
- gem.add_development_dependency "sham_rack"
23
22
  end
@@ -1,12 +1,14 @@
1
1
  require 'spec_helper'
2
2
  require 'logplex/configuration'
3
3
 
4
- describe Logplex::Configuration, 'defaults' do
5
- it 'defaults to the production heroku logplex url' do
6
- Logplex.configure { |config| }
4
+ describe Logplex::Configuration do
5
+ describe 'defaults' do
6
+ it 'defaults to the production heroku logplex url' do
7
+ Logplex.configure { |config| }
7
8
 
8
- expect(
9
- Logplex.configuration.logplex_url
10
- ).to eq('https://east.logplex.io')
9
+ expect(
10
+ Logplex.configuration.logplex_url
11
+ ).to eq('https://east.logplex.io/logs')
12
+ end
11
13
  end
12
14
  end
@@ -7,7 +7,7 @@ describe Logplex::Message do
7
7
  it 'fills out fields of a syslog message' do
8
8
  message = Logplex::Message.new(
9
9
  'my message here',
10
- token: 't.some-token',
10
+ app_name: 't.some-token',
11
11
  time: DateTime.parse("1980-08-23 05:31 00:00"),
12
12
  process: 'heroku-postgres',
13
13
  host: 'some-host',
@@ -20,17 +20,17 @@ describe Logplex::Message do
20
20
  end
21
21
 
22
22
  it 'is invalid for messages longer than 10240 bytes' do
23
- short = Logplex::Message.new('a' * 10240, token: 'foo',
23
+ short = Logplex::Message.new('a' * 10240, app_name: 'foo',
24
24
  process: 'proc',
25
25
  host: 'host')
26
- long = Logplex::Message.new('a' * 10241, token: 'foo',
26
+ long = Logplex::Message.new('a' * 10241, app_name: 'foo',
27
27
  process: 'proc',
28
28
  host: 'host')
29
29
  short.validate
30
30
  long.validate
31
31
 
32
- expect(short.valid?).to be_true
33
- expect(long.valid?).to be_false
32
+ expect(short.valid?).to be_truthy
33
+ expect(long.valid?).to be_falsey
34
34
  end
35
35
 
36
36
  it 'is invalid with no process or host' do
@@ -39,10 +39,10 @@ describe Logplex::Message do
39
39
  conf.process = nil
40
40
  end
41
41
 
42
- message = Logplex::Message.new("a message", token: 't.some-token')
42
+ message = Logplex::Message.new("a message", app_name: 't.some-token')
43
43
  message.validate
44
44
 
45
- expect(message.valid?).to be_false
45
+ expect(message.valid?).to be_falsey
46
46
  expect(message.errors[:process]).to eq ["can't be nil"]
47
47
  expect(message.errors[:host]).to eq ["can't be nil"]
48
48
  end
@@ -50,7 +50,7 @@ describe Logplex::Message do
50
50
  it 'formats logs as key/values when given a hash' do
51
51
  message = Logplex::Message.new(
52
52
  { vocals: 'Robert Plant', guitar: 'Jimmy Page' },
53
- token: 't.some-token',
53
+ app_name: 't.some-token',
54
54
  process: 'proc',
55
55
  host: 'host',
56
56
  time: DateTime.parse("1980-08-23 05:31 00:00")
@@ -1,96 +1,76 @@
1
1
  require 'spec_helper'
2
- require 'sham_rack'
3
2
  require 'logplex/publisher'
4
- require 'support/fake_logplex'
5
3
 
6
- describe Logplex::Publisher, '#publish' do
7
- before do
8
- Logplex.configure do |config|
9
- config.process = "postgres"
10
- config.host = "host"
11
- end
12
- end
13
-
14
- context 'with a working logplex' do
4
+ describe Logplex::Publisher do
5
+ describe '#publish' do
15
6
  before do
16
- ShamRack.mount(FakeLogplex.new, 'logplex.example.com', 443)
17
-
7
+ Excon.defaults[:mock] = true
8
+ Logplex.configure do |config|
9
+ config.process = "postgres"
10
+ config.host = "host"
11
+ end
18
12
  end
19
13
 
20
14
  after do
21
- ShamRack.unmount_all
22
- FakeLogplex.clear!
23
- restore_default_config
15
+ Excon.stubs.clear
24
16
  end
25
17
 
26
- it 'encodes a message and publishes it' do
27
- FakeLogplex.register_token('t.some-token')
28
-
29
- message = 'I have a message for you'
30
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
31
- publisher.publish(message)
32
-
33
- expect(FakeLogplex).to have_received_message(message)
34
- end
35
-
36
- it 'sends many messages in one request when passed an array' do
37
- FakeLogplex.register_token('t.some-token')
38
- messages = ['I have a message for you', 'here is another', 'some final thoughts']
39
-
40
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
41
-
42
- publisher.publish(messages)
43
-
44
- messages.each do |message|
45
- expect(FakeLogplex).to have_received_message(message)
18
+ context 'with a working logplex' do
19
+ after do
20
+ restore_default_config
46
21
  end
47
22
 
48
- expect(FakeLogplex.requests_received).to eq(1)
49
- end
23
+ it 'encodes a message and publishes it' do
24
+ Excon.stub({ method: :post, password: "t.some-token", body: /message for you/ }, status: 204)
25
+ message = 'I have a message for you'
26
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
27
+ publisher.publish(message)
28
+ end
50
29
 
51
- it 'does the thing' do
52
- FakeLogplex.register_token('t.some-token')
30
+ it 'sends many messages in one request when passed an array' do
31
+ Excon.stub({ method: :post, password: "t.some-token", body: /here is another/ }, status: 204)
32
+ expect(Excon).to receive(:post).once
33
+ messages = ['I have a message for you', 'here is another', 'some final thoughts']
53
34
 
54
- message = { hi: 'there' }
55
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
56
- publisher.publish(message)
35
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
57
36
 
58
- expect(FakeLogplex).to have_received_message('hi="there"')
59
- end
37
+ publisher.publish(messages)
38
+ end
60
39
 
61
- it 'returns true' do
62
- FakeLogplex.register_token('t.some-token')
40
+ it 'does the thing' do
41
+ Excon.stub({ method: :post, password: "t.some-token", body: /hi\="there\"/ }, status: 204)
42
+ message = { hi: 'there' }
43
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
44
+ expect(publisher.publish(message)).to be_truthy
45
+ end
63
46
 
64
- message = 'I have a message for you'
65
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
66
- expect(publisher.publish(message)).to be_true
67
- end
47
+ it 'returns true' do
48
+ Excon.stub({ method: :post, password: "t.some-token" }, status: 204)
49
+ message = 'I have a message for you'
50
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
51
+ expect(publisher.publish(message)).to be_truthy
52
+ end
68
53
 
69
- it "returns false when there's an auth error" do
70
- message = 'I have a message for you'
71
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
72
- expect(publisher.publish(message)).to be_false
54
+ it "returns false when there's an auth error" do
55
+ Excon.stub({ method: :post, password: "t.some-token" }, status: 401)
56
+ message = 'I have a message for you'
57
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
58
+ expect(publisher.publish(message)).to be_falsey
59
+ end
73
60
  end
74
- end
75
61
 
76
- context 'when the logplex service is acting up' do
77
- before do
78
- ShamRack.at('logplex.example.com', 443) do
79
- [500, {}, []]
62
+ context 'when the logplex service is acting up' do
63
+ it 'returns false' do
64
+ Excon.stub({ method: :post, password: "t.some-token" }, status: 500)
65
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
66
+ expect(publisher.publish('hi')).to be_falsey
80
67
  end
81
68
  end
82
69
 
83
- after { ShamRack.unmount_all }
84
-
85
- it 'returns false' do
86
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
87
- expect(publisher.publish('hi')).to be_false
70
+ it "handles timeouts" do
71
+ expect(Excon).to receive(:post).and_raise(Timeout::Error)
72
+ publisher = Logplex::Publisher.new('https://token:t.some-token@logplex.example.com')
73
+ expect(publisher.publish('hi')).to be_falsey
88
74
  end
89
75
  end
90
-
91
- it "handles timeouts" do
92
- RestClient.stub(:post).and_raise Timeout::Error
93
- publisher = Logplex::Publisher.new('t.some-token', 'https://logplex.example.com')
94
- expect(publisher.publish('hi')).to be_false
95
- end
96
76
  end
@@ -1,8 +1,6 @@
1
1
  RSpec.configure do |config|
2
- config.treat_symbols_as_metadata_keys_with_true_values = true
3
2
  config.run_all_when_everything_filtered = true
4
3
  config.filter_run :focus
5
-
6
4
  config.order = 'random'
7
5
  end
8
6
 
metadata CHANGED
@@ -1,60 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logplex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre.4
5
- prerelease: 6
4
+ version: 0.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Harold Giménez
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-02 00:00:00.000000000 Z
11
+ date: 2016-07-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: valcro
16
- requirement: &70169923645940 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70169923645940
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
- name: rest-client
27
- requirement: &70169923645520 !ruby/object:Gem::Requirement
28
- none: false
28
+ name: excon
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *70169923645520
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rspec
38
- requirement: &70169923645040 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - ">="
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *70169923645040
47
- - !ruby/object:Gem::Dependency
48
- name: sham_rack
49
- requirement: &70169923644580 !ruby/object:Gem::Requirement
50
- none: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: *70169923644580
58
55
  description: Publish and Consume Logplex messages
59
56
  email:
60
57
  - harold.gimenez@gmail.com
@@ -62,8 +59,9 @@ executables: []
62
59
  extensions: []
63
60
  extra_rdoc_files: []
64
61
  files:
65
- - .gitignore
66
- - .rspec
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
67
65
  - Gemfile
68
66
  - LICENSE
69
67
  - LICENSE.txt
@@ -79,35 +77,32 @@ files:
79
77
  - spec/logplex/message_spec.rb
80
78
  - spec/logplex/publisher_spec.rb
81
79
  - spec/spec_helper.rb
82
- - spec/support/fake_logplex.rb
83
80
  homepage: https://practiceovertheory.com
84
81
  licenses: []
82
+ metadata: {}
85
83
  post_install_message:
86
84
  rdoc_options: []
87
85
  require_paths:
88
86
  - lib
89
87
  required_ruby_version: !ruby/object:Gem::Requirement
90
- none: false
91
88
  requirements:
92
- - - ! '>='
89
+ - - ">="
93
90
  - !ruby/object:Gem::Version
94
91
  version: '0'
95
92
  required_rubygems_version: !ruby/object:Gem::Requirement
96
- none: false
97
93
  requirements:
98
- - - ! '>'
94
+ - - ">="
99
95
  - !ruby/object:Gem::Version
100
- version: 1.3.1
96
+ version: '0'
101
97
  requirements: []
102
98
  rubyforge_project:
103
- rubygems_version: 1.8.10
99
+ rubygems_version: 2.4.5.1
104
100
  signing_key:
105
- specification_version: 3
101
+ specification_version: 4
106
102
  summary: Publish and Consume Logplex messages
107
103
  test_files:
108
104
  - spec/logplex/configuration_spec.rb
109
105
  - spec/logplex/message_spec.rb
110
106
  - spec/logplex/publisher_spec.rb
111
107
  - spec/spec_helper.rb
112
- - spec/support/fake_logplex.rb
113
108
  has_rdoc:
@@ -1,108 +0,0 @@
1
- class FakeLogplex
2
- class Message
3
-
4
- attr_reader :message, :token
5
-
6
- def initialize(opts)
7
- @message = opts[:message]
8
- @token = opts[:token]
9
- end
10
-
11
- def self.from_syslog(syslog_message)
12
- messages = []
13
- anchor = 0
14
- until anchor >= syslog_message.length
15
- new_anchor, opts = extract_syslog_field(syslog_message, anchor)
16
- raise "same" if anchor == new_anchor
17
- anchor = new_anchor
18
- messages << new(opts)
19
- end
20
- messages
21
- end
22
-
23
- def self.extract_syslog_field(syslog_message, anchor)
24
- start = anchor
25
- pos = start
26
- pos, bytes = next_syslog_field(syslog_message, anchor, pos)
27
- anchor = pos+1
28
- pos, facility = next_syslog_field(syslog_message, anchor, pos)
29
- anchor = pos+1
30
- pos, time = next_syslog_field(syslog_message, anchor, pos)
31
- anchor = pos+1
32
- pos, host = next_syslog_field(syslog_message, anchor, pos)
33
- anchor = pos+1
34
- pos, token = next_syslog_field(syslog_message, anchor, pos)
35
- anchor = pos+1
36
- pos, process = next_syslog_field(syslog_message, anchor, pos)
37
- anchor = pos+1
38
- pos, message_id = next_syslog_field(syslog_message, anchor, pos)
39
- anchor = pos+1
40
- pos, unknown = next_syslog_field(syslog_message, anchor, pos)
41
- anchor = pos+1
42
-
43
- limit = start + bytes + bytes.to_s.length
44
- message = syslog_message[anchor..limit]
45
-
46
- [limit + 1, { message: message, token: token }]
47
- end
48
-
49
- def self.next_syslog_field(message, anchor, pos)
50
- until char = message[pos+=1] and char == ' '
51
- field = message[anchor..pos].to_i
52
- end
53
- [pos, field]
54
- end
55
- end
56
-
57
- @@tokens = []
58
- @@received_messages = []
59
- @@requests_received = 0
60
-
61
- def call(env)
62
- @@requests_received += 1
63
-
64
- message = env['rack.input'].read
65
- method = env['REQUEST_METHOD']
66
- path = env['PATH_INFO']
67
- content_type = env['CONTENT_TYPE']
68
- content_length = env['CONTENT_LENGTH'].to_i
69
- auth = env['HTTP_AUTHORIZATION']
70
-
71
- _, auth_token = auth.split(' ')
72
- user, pass = Base64.decode64(auth_token).split(':')
73
- if @@tokens.include?(pass)
74
- if (method == 'POST' &&
75
- path == '/logs' &&
76
- content_type == 'application/logplex-1' &&
77
- content_length == message.length)
78
-
79
- @@received_messages << Message.from_syslog(message)
80
- @@received_messages.flatten!
81
- [200, {}, []]
82
- else
83
- [404, {}, []]
84
- end
85
- else
86
- [401, {}, []]
87
- end
88
- end
89
-
90
- def self.has_received_message?(message)
91
- @@received_messages.map(&:message).include? message
92
- end
93
-
94
- def self.register_token(token)
95
- @@tokens << token
96
- end
97
-
98
- def self.clear!
99
- @@tokens = []
100
- @@received_messages = []
101
- @@requests_received = 0
102
- end
103
-
104
- def self.requests_received
105
- @@requests_received
106
- end
107
- end
108
-