logglier 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,18 +7,43 @@ Posts Logger messages to Loggly using the HTTP API.
7
7
  Usage
8
8
  -----
9
9
 
10
- require 'logglier'
10
+ require 'logglier'
11
11
 
12
- log = Logglier.new(<INPUT URL>)
12
+ log = Logglier.new(<INPUT URL>)
13
13
 
14
- log.info("hello from logglier")
14
+ log.info("hello from logglier")
15
+
16
+
17
+ ### With Rails
18
+
19
+ config/environments/production.rb
20
+
21
+ RailsApplication::Application.configure do
22
+ config.logger = Logglier.new(<INPUT URL>)
23
+ end
24
+
25
+
26
+ Input URLs
27
+ -------
28
+
29
+ ### HTTP Inputs
30
+ Logglier.new('https://logs.loggly.com/inputs/<id>')
31
+
32
+ The id is provided by loggly, look at the input's details page
33
+
34
+ ### Syslog UDP Inputs
35
+
36
+ Logglier.new('udp://<hostname>:<port>/<facility>')
37
+
38
+ The facility is optional and defaults to 16 (local0) if none is
39
+ specified.
15
40
 
16
41
 
17
42
  TODO
18
43
  -----
19
44
 
45
+ * key=value Loggly stuff.
20
46
  * Alternative https implementations (Typheous, Excon, etc). May be
21
47
  faster?
22
- * Option to use Syslog (via UDP and/or TCP) inputs. Possibly faster than
23
- the https inputs.
48
+ * Option to use Syslog TCP inputs. Possibly faster than the https inputs.
24
49
  * Do logging in a seperate thread. Is this useful? Too complex?
@@ -0,0 +1,42 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+
4
+ module Logglier
5
+
6
+ module Client
7
+
8
+ class HTTP
9
+ include Logglier::Client::InstanceMethods
10
+
11
+ attr_reader :input_uri, :http
12
+
13
+ def initialize(opts={})
14
+ setup_input_uri(opts)
15
+
16
+ @http = Net::HTTP.new(@input_uri.host, @input_uri.port)
17
+ if @input_uri.scheme == 'https'
18
+ @http.use_ssl = true
19
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
20
+ end
21
+
22
+ @http.read_timeout = opts[:read_timeout] || 2
23
+ @http.open_timeout = opts[:open_timeout] || 2
24
+ end
25
+
26
+ # Required by Logger::LogDevice
27
+ def write(message)
28
+ begin
29
+ @http.start { @http.request_post(@input_uri.path, message) }
30
+ rescue TimeoutError => e
31
+ $stderr.puts "WARNING: TimeoutError posting message: #{message}"
32
+ end
33
+ end
34
+
35
+ # Required by Logger::LogDevice
36
+ def close
37
+ nil
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,94 @@
1
+ require 'socket'
2
+ require 'uri'
3
+ require 'pp'
4
+
5
+ module Logglier
6
+
7
+ module Client
8
+
9
+ class Syslog
10
+ include Logglier::Client::InstanceMethods
11
+
12
+ attr_reader :input_uri, :facility
13
+
14
+ def initialize(opts={})
15
+ setup_input_uri(opts)
16
+ @syslog = UDPSocket.new()
17
+ @syslog.connect(@input_uri.host, @input_uri.port)
18
+
19
+ unless @input_uri.path.empty?
20
+ @facility = @input_uri.path.split('/')[1]
21
+ if @facility and @facility.to_i <= 23 && @facility.to_i >= 0
22
+ @facility = @facility.to_i
23
+ else
24
+ raise Logglier::UnknownFacility.new(@facility.to_s)
25
+ end
26
+ else
27
+ @facility = 16
28
+ end
29
+
30
+ @hostname = Socket.gethostname.split('.').first
31
+ end
32
+
33
+ # Required by Logger::LogDevice
34
+ def write(message)
35
+ begin
36
+ pp message
37
+ @syslog.send(message,0)
38
+ rescue TimeoutError => e
39
+ $stderr.puts "WARNING: TimeoutError posting message: #{message}"
40
+ end
41
+ end
42
+
43
+ # Required by Logger::LogDevice
44
+ def close
45
+ @syslog.close
46
+ end
47
+
48
+ # Specifies the date/time format for this client
49
+ def datetime_format
50
+ "%b %e %H:%M:%S"
51
+ end
52
+
53
+ # Syslog specific PRI calculation.
54
+ # See RFC3164 4.1.1
55
+ def pri(severity)
56
+ @facility + case severity
57
+ when "FATAL"
58
+ 0
59
+ when "ERROR"
60
+ 3
61
+ when "WARN"
62
+ 4
63
+ when "INFO"
64
+ 6
65
+ when "DEBUG"
66
+ 7
67
+ end
68
+ end
69
+
70
+ # Generate a syslog compat message
71
+ # See RFC3164 4.1.1 - 4.1.3
72
+ def formatter
73
+ proc do |severity, datetime, progname, msg|
74
+ message = "<#{pri(severity)}>#{datetime.strftime(datetime_format)} #{@hostname} "
75
+ if progname
76
+ message << "#{progname}: "
77
+ else
78
+ message << "#{$0}: "
79
+ end
80
+ message << "severity=#{severity},"
81
+ case msg
82
+ when Hash
83
+ msg.inject(message) {|m,v| m << "#{v[0]}=#{v[1]}" }
84
+ when String
85
+ message << msg
86
+ else
87
+ message << msg.inspect
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -1,47 +1,47 @@
1
- require 'net/https'
2
- require 'uri'
3
-
4
1
  module Logglier
5
- class Client
6
-
7
- attr_reader :input_uri, :http
8
-
9
- def initialize(opts={})
10
- opts = { :input_url => opts } if opts.is_a?(String)
11
- @input_uri = opts[:input_url]
2
+ module Client
12
3
 
4
+ def self.new(opts={})
13
5
  if opts.nil? or opts.empty?
14
6
  raise InputURLRequired.new
15
7
  end
8
+
9
+ opts = { :input_url => opts } if opts.is_a?(String)
16
10
 
17
11
  begin
18
- @input_uri = URI.parse(@input_uri)
12
+ input_uri = URI.parse(opts[:input_url])
19
13
  rescue URI::InvalidURIError => e
20
- raise InputURLRequired.new("Invalid Input URL: #{@input_uri}")
14
+ raise InputURLRequired.new("Invalid Input URL: #{input_uri}")
21
15
  end
22
16
 
23
- @http = Net::HTTP.new(@input_uri.host, @input_uri.port)
24
- if @input_uri.scheme == 'https'
25
- @http.use_ssl = true
26
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
17
+ case input_uri.scheme
18
+ when 'http', 'https'
19
+ Logglier::Client::HTTP.new(opts)
20
+ when 'udp', 'tcp'
21
+ Logglier::Client::Syslog.new(opts)
22
+ else
23
+ raise Logglier::UnsupportedScheme.new("#{input_uri.scheme} is unsupported")
27
24
  end
28
-
29
- @http.read_timeout = opts[:read_timeout] || 2
30
- @http.open_timeout = opts[:open_timeout] || 2
25
+
31
26
  end
32
27
 
33
- # Required by Logger::LogDevice
34
- def write(message)
35
- begin
36
- @http.start { @http.request_post(@input_uri.path, message) }
37
- rescue TimeoutError => e
38
- $stderr.puts "WARNING: TimeoutError posting message: #{message}"
28
+ module InstanceMethods
29
+
30
+ def setup_input_uri(opts)
31
+ @input_uri = opts[:input_url]
32
+
33
+ begin
34
+ @input_uri = URI.parse(@input_uri)
35
+ rescue URI::InvalidURIError => e
36
+ raise InputURLRequired.new("Invalid Input URL: #{@input_uri}")
37
+ end
39
38
  end
40
- end
41
39
 
42
- # Required by Logger::LogDevice
43
- def close
44
- nil
45
40
  end
41
+
46
42
  end
47
43
  end
44
+
45
+ require File.join(File.dirname(__FILE__), 'client', 'http')
46
+ require File.join(File.dirname(__FILE__), 'client', 'syslog')
47
+
@@ -1,3 +1,3 @@
1
1
  module Logglier
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/logglier.rb CHANGED
@@ -5,9 +5,22 @@ require 'logger'
5
5
  module Logglier
6
6
 
7
7
  class InputURLRequired < ArgumentError; end
8
+ class UnsupportedScheme < ArgumentError; end
9
+ class UnknownFacility < ArgumentError; end
8
10
 
9
11
  def self.new(opts={})
10
- Logger.new(Logglier::Client.new(opts))
12
+ client = Logglier::Client.new(opts)
13
+ logger = Logger.new(client)
14
+
15
+ if client.respond_to?(:formatter)
16
+ logger.formatter = client.formatter
17
+ end
18
+
19
+ if client.respond_to?(:datetime_format)
20
+ logger.datetime_format = client.datetime_format
21
+ end
22
+
23
+ logger
11
24
  end
12
25
 
13
26
  end
data/spec/client_spec.rb CHANGED
@@ -14,15 +14,38 @@ describe Logglier::Client do
14
14
 
15
15
  context "a single string param" do
16
16
 
17
- context "that is a valid uri" do
17
+ context "that is a valid http uri" do
18
18
 
19
- it "should return and instance of itself" do
19
+ it "should return an instance of the proper client" do
20
20
  log = Logglier::Client.new('http://localhost')
21
- log.should be_an_instance_of Logglier::Client
21
+ log.should be_an_instance_of Logglier::Client::HTTP
22
22
  end
23
23
 
24
24
  end
25
25
 
26
+ context "that is a valid udp uri" do
27
+
28
+ it "should return an instance of the proper client" do
29
+ log = Logglier::Client.new('udp://logs.loggly.com:42538')
30
+ log.should be_an_instance_of Logglier::Client::Syslog
31
+ end
32
+ end
33
+
34
+ context "that is a valid tcp uri" do
35
+
36
+ it "should return an instance of the proper client" do
37
+ log = Logglier::Client.new('tcp://logs.loggly.com:42538')
38
+ log.should be_an_instance_of Logglier::Client::Syslog
39
+ end
40
+ end
41
+
42
+ context "valid url with a scheme not supported" do
43
+
44
+ it "should raise an error" do
45
+ expect { Logglier::Client.new('foo://bar:1234') }.to raise_error Logglier::UnsupportedScheme
46
+ end
47
+ end
48
+
26
49
  context "that is NOT a valid uri" do
27
50
 
28
51
  it "should raise an error" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logglier
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Edward Muller (aka freeformz)
@@ -66,6 +66,8 @@ files:
66
66
  - ./lib/logglier.rb
67
67
  - ./lib/logglier/client.rb
68
68
  - ./lib/logglier/version.rb
69
+ - ./lib/logglier/client/http.rb
70
+ - ./lib/logglier/client/syslog.rb
69
71
  - ./spec/client_spec.rb
70
72
  - ./spec/logglier_spec.rb
71
73
  - ./spec/spec_helper.rb