omloga 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0120863a25a06fc3a0f1071965b346b3e4d254c1
4
+ data.tar.gz: d7fa15b01f36a9a4e796e4c4e000c8d893bdb0eb
5
+ SHA512:
6
+ metadata.gz: 669be8047715977a016802a9a0e6723c1868591ee59c8a1c839d6067d2027a83406aeaea4b62e75b60d0a8c2f989c02e42d85cca6db5a79b37dca970fcf0a15c
7
+ data.tar.gz: ab4a597930ae7f02dbf7b563838b5257e06e45c60b12fbdd43d99525148100a86b6236518386f2e1c47469ad202ba94daf32d41ef83a5b4732e54ba35aca93ef
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ omloga
2
+ ======
3
+
4
+ A Ruby on Rails log parser and stitcher.
data/bin/omloga ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'omloga'
4
+
5
+ omloga(ARGV)
@@ -0,0 +1,48 @@
1
+ #encoding: utf-8
2
+
3
+ require 'moped'
4
+
5
+ module Omloga
6
+ class Request
7
+ attr_accessor :id, :pid, :saved, :lines, :count, :complete_count, :path, :status, :created_at, :updated_at
8
+
9
+ def initialize(pid, start_line)
10
+ @id = Moped::BSON::ObjectId.new
11
+ @pid = pid
12
+ @saved = false
13
+ @count = 1
14
+ @complete_count = 0
15
+ @lines = [start_line.to_s]
16
+ end
17
+
18
+ def mongo_doc
19
+ obj = {
20
+ '_id' => id,
21
+ 'pid' => pid,
22
+ 'count' => count,
23
+ 'lines' => lines.join("")
24
+ }
25
+
26
+ if saved
27
+ obj['updated_at'] = Time.now
28
+ else
29
+ obj['created_at'] = obj['updated_at'] = Time.now
30
+ end
31
+ obj
32
+ end
33
+
34
+ def id_doc
35
+ {'_id' => id }
36
+ end
37
+
38
+ def add_line_special(line, pos)
39
+ line = line.to_s
40
+ lines.insert(line, pos.to_i)
41
+ rescue StandardError => e
42
+ puts "\nline = \n#{line} | is_last = #{is_last}"
43
+ puts e.message
44
+ puts e.backtrace.join("\n")
45
+ exit
46
+ end
47
+ end #__End of class Request__
48
+ end #__End of module Omloga__
data/lib/omloga.rb ADDED
@@ -0,0 +1,148 @@
1
+ require 'moped'
2
+ require 'optparse'
3
+ require 'ostruct'
4
+ require 'omloga/request'
5
+
6
+ def omloga(args)
7
+
8
+ options = OpenStruct.new
9
+
10
+ opts_parser = OptionParser.new do |opts|
11
+
12
+ opts.banner = "\nUsage : omloga -d <mongodb-uri> -c <collection-name> [OPTIONS] <log-file-path>"
13
+
14
+ opts.separator ""
15
+
16
+ opts.on('-d', '--dburi Mongodb-URI', 'MongoDB URI with username/password (if needed) and DB name') do |uri|
17
+ options.dburi = uri
18
+ end
19
+
20
+ opts.on('-c', '--collection Collection-Name', 'Name of the collection where the log lines should be stored') do |c|
21
+ options.collection = c
22
+ end
23
+
24
+ opts.on('--log-skip SKIP-FILE-PATH', 'Logs the skipped lines to the specified file') do |sf|
25
+ options.skip_file_path = sf
26
+ end
27
+
28
+ opts.on_tail('-h', '--help', 'Show this help message') do
29
+ puts opts
30
+ exit
31
+ end
32
+ end
33
+
34
+ opts_parser.parse!(args)
35
+
36
+ if args.length < 1
37
+ puts "Insufficient number of arguments"
38
+ puts opts_parser
39
+ exit
40
+ end
41
+
42
+ def db_session
43
+ $DB_SESSION
44
+ end
45
+
46
+ def logs_collection
47
+ $DB_LOGS_COLLECTION
48
+ end
49
+
50
+ def request_hash
51
+ $REQUEST_HASH
52
+ end
53
+
54
+ $DB_SESSION = Moped::Session.connect(options.dburi)
55
+ $DB_LOGS_COLLECTION = db_session[options.collection]
56
+ $REQUEST_HASH = {}
57
+ $LOG_FILE = args[0]
58
+
59
+ def is_start_line?(line)
60
+ line = line.to_s
61
+ return false if line.nil? or line.length < 7 # "Started" is 7 characters long. It is minimal
62
+
63
+ if line.match(/Started/).nil?
64
+ false
65
+ else
66
+ true
67
+ end
68
+ end
69
+
70
+ def is_complete_line?(line)
71
+ line = line.to_s
72
+ return false if line.nil? or line.length < 9 # "Completed" is 9 characters long. It is minimal
73
+
74
+ if line.match(/Completed/).nil?
75
+ false
76
+ else
77
+ true
78
+ end
79
+ end
80
+
81
+ def get_pid(line)
82
+ match_data = line.match(/#([0-9]+)\]/)
83
+ if match_data
84
+ return match_data[1]
85
+ else
86
+ return nil
87
+ end
88
+ end
89
+
90
+ line_count = 0
91
+ request_count = 0
92
+ lines_skipped = 0
93
+ status_str = ''
94
+ $stdout.sync = true
95
+ log_skip = false
96
+ if options.skip_file_path
97
+ skipped_lines = File.open(options.skip_file_path, 'a')
98
+ log_skip = true
99
+ end
100
+
101
+ File.foreach($LOG_FILE) do |log_line|
102
+ pid = get_pid(log_line)
103
+ req = request_hash[pid]
104
+
105
+ if is_start_line?(log_line)
106
+ if req
107
+ req.lines << log_line
108
+ req.count+= 1
109
+ else
110
+ req = Omloga::Request.new(pid, log_line)
111
+ request_hash[pid] = req
112
+ end
113
+ else
114
+ unless req
115
+ lines_skipped+= 1
116
+ skipped_lines.print log_line if log_skip
117
+ next
118
+ end
119
+ is_complete = is_complete_line?(log_line)
120
+ req.lines << log_line
121
+
122
+ if is_complete
123
+ req.complete_count+= 1
124
+
125
+ if req.complete_count >= req.count
126
+ logs_collection.find(req.id_doc).upsert(req.mongo_doc)
127
+ request_hash.delete(pid)
128
+ request_count+= req.count
129
+ end
130
+ end
131
+ end
132
+ line_count+= 1
133
+
134
+ status_str.length.times { print "\b" }
135
+
136
+ status_str = "Lines Processed : #{line_count} | Requests found : #{request_count} | Lines Skipped : #{lines_skipped}"
137
+ print status_str
138
+ end
139
+
140
+ puts ""
141
+
142
+ if log_skip
143
+ puts "Skipped lines have been written to : #{options.skip_file_path}"
144
+ skipped_lines.close
145
+ end
146
+
147
+ puts "\nDone..!"
148
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omloga
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Srirang G Doddihal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: moped
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.3
27
+ description: Stitches together log lines of every request and inserts them as one
28
+ record in MongoDB for easier analysis
29
+ email: om.brahmana@gmail.com
30
+ executables:
31
+ - omloga
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/omloga.rb
36
+ - lib/omloga/request.rb
37
+ - README.md
38
+ - bin/omloga
39
+ homepage: http://rubygems.org/gems/omloga
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.0.3
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: A Ruby on Rails log parser and stitcher.
63
+ test_files: []