Http_Error_Log 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/Gemfile +6 -0
- data/Http_Error_Log.gemspec +32 -0
- data/README.md +53 -0
- data/Rakefile +3 -0
- data/lib/Http_Error_Log.rb +64 -0
- data/lib/Http_Error_Log/version.rb +1 -0
- data/spec/Http_Error_Log.rb +63 -0
- data/spec/bin.rb +13 -0
- data/spec/file/empty.log +0 -0
- data/spec/file/nginx.error.log +4 -0
- data/spec/lib/main.rb +48 -0
- metadata +138 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "Http_Error_Log/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "Http_Error_Log"
|
8
|
+
s.version = Http_Error_Log_VERSION
|
9
|
+
s.authors = ["da99"]
|
10
|
+
s.email = ["i-hate-spam-45671204@mailinator.com"]
|
11
|
+
s.homepage = "https://github.com/da99/Http_Error_Log"
|
12
|
+
s.summary = %q{Parse error.log from servers.}
|
13
|
+
s.description = %q{
|
14
|
+
|
15
|
+
Turns your error.log from a server into a Ruby data structure.
|
16
|
+
Read me at the homepage.
|
17
|
+
|
18
|
+
}
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
s.add_development_dependency 'bacon'
|
26
|
+
s.add_development_dependency 'rake'
|
27
|
+
s.add_development_dependency 'Bacon_Colored'
|
28
|
+
s.add_development_dependency 'pry'
|
29
|
+
|
30
|
+
# Specify any dependencies here; for example:
|
31
|
+
s.add_runtime_dependency 'Split_Lines'
|
32
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
Http\_Error\_Log
|
3
|
+
================
|
4
|
+
|
5
|
+
A Ruby gem to turn an error log (eg Nginx error.log) into
|
6
|
+
Ruby data structures:
|
7
|
+
|
8
|
+
2012/01/01 01:01:01 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream, client: 11.11.11.11, server: test.test.com, request: "GET /stylesheets/en-us/, , .css?time=1286211794 HTTP/1.1", upstream: "http://127.0.0.1:4567/test/en-us/Test-Page.css?time=1234.5678", host: "www.test.com", referrer: "http://www.test.com/"
|
9
|
+
|
10
|
+
# ->
|
11
|
+
[ { :created_at=>Time, :upstreatm=>String, ...} ]
|
12
|
+
|
13
|
+
Installation
|
14
|
+
------------
|
15
|
+
|
16
|
+
gem install Http_Error_Log
|
17
|
+
|
18
|
+
Usage
|
19
|
+
------
|
20
|
+
|
21
|
+
require "Http_Error_Log"
|
22
|
+
|
23
|
+
Http_Error_Log "/my/nginx/error.log"
|
24
|
+
# --> [ Hash, Hash, Hash ]
|
25
|
+
|
26
|
+
Each Hash object has:
|
27
|
+
|
28
|
+
:line => 12 # Integer
|
29
|
+
:created_at => Time.parse(str) # Time object.
|
30
|
+
:backtrace => [ "file:num:[error] 11563#0"]
|
31
|
+
:message => "*183 connect() failed (111: Connection refused) while connecting to upstream"
|
32
|
+
|
33
|
+
Skip records using a date/time string:
|
34
|
+
|
35
|
+
Http_Error_Log "err.log", '2012/04/04 04:04:04'
|
36
|
+
|
37
|
+
# --> Skips records that are less OR equal to:
|
38
|
+
# '2012/04/04 04:04:04'
|
39
|
+
|
40
|
+
Run Tests
|
41
|
+
---------
|
42
|
+
|
43
|
+
git clone git@github.com:da99/Http_Error_Log.git
|
44
|
+
cd Http_Error_Log
|
45
|
+
bundle update
|
46
|
+
bundle exec bacon spec/lib/main.rb
|
47
|
+
|
48
|
+
"I hate writing."
|
49
|
+
-----------------------------
|
50
|
+
|
51
|
+
If you know of existing software that makes the above redundant,
|
52
|
+
please tell me. The last thing I want to do is maintain code.
|
53
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'Http_Error_Log/version'
|
2
|
+
require 'Split_Lines'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
def Http_Error_Log file, skip = nil
|
6
|
+
h = Http_Error_Log_Helper
|
7
|
+
|
8
|
+
lines = Split_Lines(File.read( file ))
|
9
|
+
lines
|
10
|
+
.map { |l|
|
11
|
+
|
12
|
+
pieces = l.split %r!,?\s+([\w\_\.\-]+):\s+!
|
13
|
+
|
14
|
+
prefix = pieces.shift
|
15
|
+
time_str = prefix.split[0,2].join(' ')
|
16
|
+
|
17
|
+
next if skip && Time.parse(time_str) <= Time.parse(skip)
|
18
|
+
|
19
|
+
pieces.each_index { |i|
|
20
|
+
if i.even?
|
21
|
+
pieces[i] = pieces[i].to_sym
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
final = Hash[ *pieces ]
|
26
|
+
final[:created_at], final[:error], final[:msg] = h.to_time(prefix)
|
27
|
+
|
28
|
+
final
|
29
|
+
|
30
|
+
}.compact
|
31
|
+
end # === def Http_Error_Log
|
32
|
+
|
33
|
+
class Http_Error_Log_Helper
|
34
|
+
|
35
|
+
class << self
|
36
|
+
|
37
|
+
def to_kv str
|
38
|
+
pieces = str.split(':')
|
39
|
+
k = pieces.shift
|
40
|
+
v = pieces.join(':')
|
41
|
+
[ k.strip.to_sym, v.strip ]
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Example input:
|
46
|
+
# "2012/05/08 04:08:19 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream"
|
47
|
+
#
|
48
|
+
# Output:
|
49
|
+
# [ Time, '[error] 1156#0', rest ]
|
50
|
+
#
|
51
|
+
def to_time str
|
52
|
+
pieces = str.split
|
53
|
+
date = pieces.shift
|
54
|
+
time = pieces.shift
|
55
|
+
|
56
|
+
err, msg = pieces.join(' ').split(':')
|
57
|
+
|
58
|
+
[ Time.parse("#{date} #{time}" ), err, msg]
|
59
|
+
end
|
60
|
+
|
61
|
+
end # === << self
|
62
|
+
|
63
|
+
|
64
|
+
end # === Http_Error_Log_Helper
|
@@ -0,0 +1 @@
|
|
1
|
+
Http_Error_Log_VERSION = "0.1.0"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
describe "Http_Error_Log 'file'" do
|
3
|
+
|
4
|
+
it "turns file into an Array" do
|
5
|
+
NGINX_ERROR_LOG
|
6
|
+
.should.is_a Array
|
7
|
+
end
|
8
|
+
|
9
|
+
it "defines keys as symbols: client server request upstream host referrer created_at error msg" do
|
10
|
+
%w{
|
11
|
+
client server request upstream host referrer created_at error msg
|
12
|
+
}.each { |k|
|
13
|
+
NGINX_ERROR_LOG.first.should.has_key k.to_sym
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets key: :created_at" do
|
18
|
+
key_should_be :created_at, Time.parse('2012/01/01 01:01:01')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets key: :client" do
|
22
|
+
key_should_be :client, '11.11.11.11'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets key: :server" do
|
26
|
+
key_should_be :server, 'test.test.com'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "sets key: :host" do
|
30
|
+
key_should_be :host, '"www.test.com"'
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets key: :request" do
|
34
|
+
key_should_be :request, "GET /stylesheets/en-us/, , .css?time=1286211794 HTTP/1.1".inspect
|
35
|
+
end
|
36
|
+
|
37
|
+
it "sets key: :referrer" do
|
38
|
+
key_should_be :referrer, '"http://www.test.com/"'
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
it "sets key: upstream" do
|
43
|
+
key_should_be :upstream, "http://127.0.0.1:4567/test/en-us/Test-Page.css?time=1234.5678".inspect
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
it "returns an empty array if file is empty" do
|
48
|
+
EMPTY_LOG
|
49
|
+
.should == []
|
50
|
+
end
|
51
|
+
|
52
|
+
end # === Http_Error_Log 'file'
|
53
|
+
|
54
|
+
describe "Http_Error_Log :file, \"date time\"" do
|
55
|
+
|
56
|
+
it "skips all entries that come after a specified" do
|
57
|
+
target = NGINX_ERROR_LOG[1, NGINX_ERROR_LOG.size]
|
58
|
+
Http_Error_Log("spec/file/nginx.error.log", "2012/01/01 01:01:01 ")
|
59
|
+
.should == target
|
60
|
+
end
|
61
|
+
|
62
|
+
end # === Http_Error_Log :file, \"skip\"
|
63
|
+
|
data/spec/bin.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
bins = Dir.glob("bin/*")
|
3
|
+
|
4
|
+
unless bins.empty?
|
5
|
+
describe "permissions of bin/" do
|
6
|
+
bins.each { |file|
|
7
|
+
it "should chmod 755 for: #{file}" do
|
8
|
+
`stat -c %a #{file}`.strip
|
9
|
+
.should.be == "755"
|
10
|
+
end
|
11
|
+
}
|
12
|
+
end # === permissions of bin/
|
13
|
+
end # === unless bins.empty?
|
data/spec/file/empty.log
ADDED
File without changes
|
@@ -0,0 +1,4 @@
|
|
1
|
+
2012/01/01 01:01:01 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream, client: 11.11.11.11, server: test.test.com, request: "GET /stylesheets/en-us/, , .css?time=1286211794 HTTP/1.1", upstream: "http://127.0.0.1:4567/test/en-us/Test-Page.css?time=1234.5678", host: "www.test.com", referrer: "http://www.test.com/"
|
2
|
+
2012/02/02 02:02:02 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream, client: 22.22.22.22, server: test.test.com, request: "GET /stylesheets/en-us/+, .css?time=1286211794 HTTP/1.1", upstream: "http://127.0.0.1:4567/2/en-us/+, 2.css?time=2", host: "www.test.com", referrer: "http://www.test.com/"
|
3
|
+
2012/03/03 03:03:03 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream, client: 33.33.33.33, server: test.test.com, request: "GET /stylesheets/en-us/+, .css?time=1386311794 HTTP/1.1", upstream: "http://137.0.0.1:4567/3/en-us/+, 3.css?time=3", host: "www.test.com", referrer: "http://www.test.com/"
|
4
|
+
2012/04/04 04:04:04 [error] 11563#0: *183 connect() failed (111: Connection refused) while connecting to upstream, client: 44.44.44.44, server: test.test.com, request: "GET /stylesheets/en-us/+, .css?time=1486411794 HTTP/1.1", upstream: "http://147.0.0.1:4567/4/en-us/+, 4.css?time=4", host: "www.test.com", referrer: "http://www.test.com/"
|
data/spec/lib/main.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.print e.message, "\n"
|
8
|
+
$stderr.print "Run `bundle install` to install missing gems\n"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
require 'bacon'
|
12
|
+
|
13
|
+
Gem_Dir = File.expand_path( File.join(File.dirname(__FILE__) + '/../..') )
|
14
|
+
$LOAD_PATH.unshift Gem_Dir
|
15
|
+
$LOAD_PATH.unshift( Gem_Dir + "/lib" )
|
16
|
+
|
17
|
+
Bacon.summary_on_exit
|
18
|
+
|
19
|
+
require 'Http_Error_Log'
|
20
|
+
require 'Bacon_Colored'
|
21
|
+
require 'pry'
|
22
|
+
|
23
|
+
# ======== Custom code =============
|
24
|
+
#
|
25
|
+
|
26
|
+
NGINX_ERROR_LOG = Http_Error_Log("spec/file/nginx.error.log")
|
27
|
+
EMPTY_LOG = Http_Error_Log("spec/file/empty.log")
|
28
|
+
|
29
|
+
class Bacon::Context
|
30
|
+
def key_should_be k, v
|
31
|
+
NGINX_ERROR_LOG.first[k].should == v
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# ======== Include the tests.
|
36
|
+
target_files = ARGV[1, ARGV.size - 1].select { |a| File.file?(a) }
|
37
|
+
|
38
|
+
if target_files.empty?
|
39
|
+
|
40
|
+
# include all files
|
41
|
+
Dir.glob('./spec/*.rb').each { |file|
|
42
|
+
require file.sub('.rb', '') if File.file?(file)
|
43
|
+
}
|
44
|
+
|
45
|
+
else
|
46
|
+
# Do nothing. Bacon grabs the file.
|
47
|
+
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Http_Error_Log
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- da99
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bacon
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: Bacon_Colored
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: Split_Lines
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: ! "\n\n Turns your error.log from a server into a Ruby data structure.\n
|
95
|
+
\ Read me at the homepage.\n \n "
|
96
|
+
email:
|
97
|
+
- i-hate-spam-45671204@mailinator.com
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- Gemfile
|
104
|
+
- Http_Error_Log.gemspec
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- lib/Http_Error_Log.rb
|
108
|
+
- lib/Http_Error_Log/version.rb
|
109
|
+
- spec/Http_Error_Log.rb
|
110
|
+
- spec/bin.rb
|
111
|
+
- spec/file/empty.log
|
112
|
+
- spec/file/nginx.error.log
|
113
|
+
- spec/lib/main.rb
|
114
|
+
homepage: https://github.com/da99/Http_Error_Log
|
115
|
+
licenses: []
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 1.8.23
|
135
|
+
signing_key:
|
136
|
+
specification_version: 3
|
137
|
+
summary: Parse error.log from servers.
|
138
|
+
test_files: []
|