gelfd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+