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 +30 -5
- data/lib/logglier/client/http.rb +42 -0
- data/lib/logglier/client/syslog.rb +94 -0
- data/lib/logglier/client.rb +29 -29
- data/lib/logglier/version.rb +1 -1
- data/lib/logglier.rb +14 -1
- data/spec/client_spec.rb +26 -3
- metadata +5 -3
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
|
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
|
data/lib/logglier/client.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
|
-
require 'net/https'
|
2
|
-
require 'uri'
|
3
|
-
|
4
1
|
module Logglier
|
5
|
-
|
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
|
-
|
12
|
+
input_uri = URI.parse(opts[:input_url])
|
19
13
|
rescue URI::InvalidURIError => e
|
20
|
-
raise InputURLRequired.new("Invalid Input URL: #{
|
14
|
+
raise InputURLRequired.new("Invalid Input URL: #{input_uri}")
|
21
15
|
end
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@
|
37
|
-
|
38
|
-
|
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
|
+
|
data/lib/logglier/version.rb
CHANGED
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
|
-
|
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
|
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:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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
|