gelfd 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gelfd.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # gelfd
2
+ gelfd is a standalone implementation of GELF (Graylog2 Extended Log Format).
3
+ This is used by the graylog2 server as an extended format for handling log messages.
4
+
5
+ ## Rationale
6
+ This was originally concieved as a way to provide a graylog2-compatible input for logstash.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/gelfd ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
3
+ require 'socket'
4
+ require 'gelfd'
5
+
6
+ server = UDPSocket.new
7
+ puts "Starting up"
8
+ server.bind(nil, 11211)
9
+ trap("INT") { puts "Shutting down"; exit }
10
+
11
+ loop do
12
+ data, addr = server.recvfrom(8192)
13
+ begin
14
+ res = Gelfd::Parser.parse(data)
15
+ rescue Exception => e
16
+ puts e.message
17
+ end
18
+ puts res unless res.nil?
19
+ end
data/gelfd.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "gelfd/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gelfd"
7
+ s.version = Gelfd::VERSION
8
+ s.authors = ["John E. Vincent"]
9
+ s.email = ["lusis.org+github.com@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Pure ruby gelf server and decoding library}
12
+ s.description = %q{Standalone implementation of the Graylog Extended Log Format}
13
+
14
+ s.rubyforge_project = "gelfd"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
data/lib/gelfd.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "gelfd/version"
2
+
3
+ module Gelfd
4
+ CHUNKED_MAGIC = [0x1e,0x0f].pack('C*').freeze
5
+ ZLIB_MAGIC = [0x78,0x9c].pack('C*').freeze
6
+ GZIP_MAGIC = [0x1f,0x8b].pack('C*').freeze
7
+ HEADER_LENGTH = 12
8
+ DATA_LENGTH = 8192 - HEADER_LENGTH
9
+ MAX_CHUNKS = 128
10
+ end
11
+
12
+ require File.join(File.dirname(__FILE__), 'gelfd', 'exceptions')
13
+ require File.join(File.dirname(__FILE__), 'gelfd', 'zlib_parser')
14
+ require File.join(File.dirname(__FILE__), 'gelfd', 'gzip_parser')
15
+ require File.join(File.dirname(__FILE__), 'gelfd', 'chunked_parser')
16
+ require File.join(File.dirname(__FILE__), 'gelfd', 'parser')
@@ -0,0 +1,46 @@
1
+ module Gelfd
2
+ class ChunkedParser
3
+ @@chunk_map = Hash.new {|hash,key| hash[key] = {:total_chunks => 0, :chunks => {} } }
4
+
5
+ attr_accessor :message_id, :max_chunks, :decoded_data, :chunks, :seen
6
+
7
+ def self.parse(data)
8
+ msg_id = self.parse_chunk(data)
9
+ if @@chunk_map[msg_id][:chunks].size == @@chunk_map[msg_id][:total_chunks]
10
+ assemble_chunks(msg_id)
11
+ end
12
+ end
13
+
14
+ def self.assemble_chunks(msg_id)
15
+ buff = ''
16
+ chunks = @@chunk_map[msg_id][:chunks]
17
+ chunks.keys.sort.each do |k|
18
+ buff += chunks[k]
19
+ end
20
+ begin
21
+ # TODO
22
+ # This has a chance for an DoS
23
+ # you can send a chunked message as a chunked message
24
+ t = Parser.parse(buff.clone)
25
+ t
26
+ rescue Exception => e
27
+ "Exception: #{e.message}"
28
+ end
29
+ end
30
+
31
+ private
32
+ def self.parse_chunk(data)
33
+ header = data[0..1]
34
+ raise NotChunkedDataError, "This doesn't look like a Chunked GELF message!" if header != CHUNKED_MAGIC
35
+ begin
36
+ msg_id = data[2..9].unpack('C*').join
37
+ seq_number, total_number = data[10].ord, data[11].ord
38
+ zlib_chunk = data[12..-1]
39
+ raise TooManyChunksError, "#{total_number} greater than #{MAX_CHUNKS}" if total_number > MAX_CHUNKS
40
+ @@chunk_map[msg_id][:total_chunks] = total_number.to_i
41
+ @@chunk_map[msg_id][:chunks].merge!({seq_number.to_i => zlib_chunk})
42
+ msg_id
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ module Gelfd
2
+ class NotChunkedDataError < StandardError; end
3
+ class DuplicateChunkError < StandardError; end
4
+ class TooManyChunksError < StandardError; end
5
+ class UnknownHeaderError < StandardError; end
6
+ class DecodeError < StandardError; end
7
+ class NotYetImplementedError < StandardError; end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Gelfd
2
+ class GzipParser
3
+
4
+ def self.parse(data)
5
+ raise NotYetImplementedError, "GZip decoding is not yet implemented"
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module Gelfd
2
+ class Parser
3
+
4
+ def self.parse(data)
5
+ header = data[0..1]
6
+ case header
7
+ when ZLIB_MAGIC
8
+ ZlibParser.parse(data)
9
+ when CHUNKED_MAGIC
10
+ ChunkedParser.parse(data)
11
+ when GZIP_MAGIC
12
+ GzipParser.parse(data)
13
+ else
14
+ raise UnknownHeaderError, "Could not find parser for header: #{header.unpack('C*').to_s}"
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+
@@ -0,0 +1,3 @@
1
+ module Gelfd
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'zlib'
2
+ module Gelfd
3
+ class ZlibParser
4
+
5
+ def self.parse(data)
6
+ begin
7
+ t = Zlib::Inflate.inflate(data)
8
+ t
9
+ rescue Exception => e
10
+ raise DecodeError, "Failed to decode data: #{e}"
11
+ end
12
+ end
13
+
14
+ end
15
+ end
Binary file
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gelfd
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - John E. Vincent
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-09-09 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Standalone implementation of the Graylog Extended Log Format
17
+ email:
18
+ - lusis.org+github.com@gmail.com
19
+ executables:
20
+ - gelfd
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - README.md
29
+ - Rakefile
30
+ - bin/gelfd
31
+ - gelfd.gemspec
32
+ - lib/gelfd.rb
33
+ - lib/gelfd/chunked_parser.rb
34
+ - lib/gelfd/exceptions.rb
35
+ - lib/gelfd/gzip_parser.rb
36
+ - lib/gelfd/parser.rb
37
+ - lib/gelfd/version.rb
38
+ - lib/gelfd/zlib_parser.rb
39
+ - test/fixtures/unchunked.zl
40
+ homepage: ""
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project: gelfd
63
+ rubygems_version: 1.8.6
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Pure ruby gelf server and decoding library
67
+ test_files: []
68
+