nginx_utils 0.0.5 → 0.0.6

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/bin/nginx_utils ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: utf-8
3
+
4
+ require "nginx_utils"
5
+
6
+ NginxUtils::CLI.start
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+
3
+ module NginxUtils
4
+ class CLI < Thor
5
+ desc "status example.com", "Print status of Nginx"
6
+ long_desc <<-LONGDESC
7
+ `status` to view the status of Nginx.
8
+ LONGDESC
9
+ option :only_value, type: :boolean, desc: "print status value only."
10
+ def status(host="localhost")
11
+ result = NginxUtils::Status.get host: host
12
+ if options[:only_value]
13
+ puts result.values.join("\t")
14
+ else
15
+ puts "Active Connections: #{result[:active_connection]}"
16
+ puts "Accepts: #{result[:accepts]} Handled: #{result[:handled]} Requests: #{result[:requests]}"
17
+ puts "Reading: #{result[:reading]} Writing: #{result[:writing]} Waiting: #{result[:waiting]}"
18
+ end
19
+ end
20
+
21
+ desc "logrotate -d", "Nginx logrotate"
22
+ long_desc <<-LONGDESC
23
+ `logrotate` will log rotation of Nginx.
24
+ LONGDESC
25
+ option :debug, type: :boolean, aliases: "-d", desc: "Debug mode. Run only log output to STDOUT."
26
+ option :script_log, desc: "Log file for script."
27
+ option :log_level, desc: "Log level of script log."
28
+ option :root_dir, desc: "Root directory of Nginx."
29
+ option :target_logs, desc: "Specify logs of target."
30
+ option :retention, desc: "Specify in days the retention period of log."
31
+ option :pid_file, desc: "PID file of Nginx"
32
+ def logrotate
33
+ NginxUtils::Logrotate.new(options).execute
34
+ end
35
+ end
36
+ end
@@ -5,7 +5,7 @@ module NginxUtils
5
5
  include Enumerable
6
6
 
7
7
  def initialize(log, options={})
8
- @log = File.open(log, "r")
8
+ @log = File.open(log)
9
9
 
10
10
  if options[:parser]
11
11
  if options[:parser].is_a? Regexp
@@ -27,7 +27,7 @@ module NginxUtils
27
27
 
28
28
  private
29
29
  def parse(line)
30
- case @format
30
+ case @format.to_sym
31
31
  when :ltsv then
32
32
  row = line.split("\t").map do |f|
33
33
  c = f.split(":")
@@ -7,111 +7,16 @@ module NginxUtils
7
7
  attr_accessor :delete_logs
8
8
 
9
9
  def initialize(options={})
10
- # Debug
11
- # debug: false => Not execute. Only output of logs to STDOUT.
12
- # debug: true => Execute rotate logs Nginx. (default)
13
- if options[:debug]
14
- debug
15
- else
16
- @execute = true
17
-
18
- # Script log file
19
- # not specified => /tmp/nginx_rotate.log (default)
20
- # script_log: false => Not output of logs.
21
- # script_log: "/path/to/nginx_rotate.log" => /path/to/nginx_rotate.log
22
- # script_log: STDOUT => STDOUT
23
- set_logger options[:script_log]
24
-
25
- # Script log level
26
- # not specified => Logger::DEBUG (default)
27
- # log_level: [:fatal|:error|:info|:warn]
28
- set_log_level options[:log_level]
29
- end
30
-
31
- # Target logs
32
- # Log of rename target is "#{root_dir}/**/#{target_logs}"
33
- # Log of delete target is "#{root_dir}/**/#{target_logs}.*"
34
- # Default parameters are as follows:
35
- # - root_dir => /usr/local/nginx
36
- # - target_logs => *.log
37
- @root_dir = options[:root_dir] || "/usr/local/nginx"
38
- @target_logs = options[:target_logs] || "*.log"
39
- @rename_logs = Dir.glob(File.join(@root_dir, "**", @target_logs))
40
- @delete_logs = Dir.glob(File.join(@root_dir, "**", "#{@target_logs}.*"))
41
-
42
- # Rename prefix
43
- # Log of rename target to add the prefix.
44
- # File name of the renamed after: "#{filename}.#{prefix}"
45
- # Current time default. (YYYYmmddHHMMSS)
46
- @prefix = options[:prefix] || Time.now.strftime("%Y%m%d%H%M%S")
47
-
48
- # Retention period
49
- # Delete log last modification time has passed the retention period.
50
- # Specified unit of day.
51
- dates = options[:retention] || 90
52
- @retention = Time.now - (dates.to_i * 3600 * 24)
53
-
54
- # PID file of Nginx
55
- # The default is "#{root_dir}/logs/nginx.pid".
56
- @pid_file = options[:pid_file] || File.join(@root_dir, "logs", "nginx.pid")
10
+ configure(options)
57
11
  end
58
12
 
59
13
  def config(options={})
60
- # Debug
61
- unless options[:debug].nil?
62
- if options[:debug]
63
- debug
64
- else
65
- debug false
66
- end
67
- end
68
-
69
- # Script log file
70
- unless options[:script_log].nil?
71
- set_logger options[:script_log]
72
- end
73
-
74
- # Script log level
75
- unless options[:log_level].nil?
76
- set_log_level options[:log_level]
77
- end
78
-
79
- # Target logs
80
- reglog = false
81
- unless options[:root_dir].nil?
82
- @root_dir = options[:root_dir]
83
- reglob = true
84
- end
85
-
86
- unless options[:target_logs].nil?
87
- @target_logs = options[:target_logs]
88
- reglob = true
89
- end
90
-
91
- if reglob
92
- @rename_logs = Dir.glob(File.join(@root_dir, "**", @target_logs))
93
- @delete_logs = Dir.glob(File.join(@root_dir, "**", "#{@target_logs}.*"))
94
- end
95
-
96
- # Rename prefix
97
- unless options[:prefix].nil?
98
- @prefix = options[:prefix]
99
- end
100
-
101
- # Retention period
102
- unless options[:retention].nil?
103
- @retention = Time.now - (options[:retention].to_i * 3600 * 24)
104
- end
105
-
106
- # PID file of Nginx
107
- unless options[:pid_file].nil?
108
- @pid_file = options[:pid_file]
109
- end
14
+ configure(options)
110
15
  end
111
16
 
112
17
  def rename
113
18
  @rename_logs.each do |log|
114
- after = "#{log}.#{@prefix}"
19
+ after = "#{log}.#{@params[:prefix]}"
115
20
  if File.exists? after
116
21
  @logger.warn "File already exists: #{after}" if @logger
117
22
  else
@@ -122,8 +27,10 @@ module NginxUtils
122
27
  end
123
28
 
124
29
  def delete
30
+ retention_time = Time.now - (@params[:retention].to_i * 3600 * 24)
31
+
125
32
  @delete_logs.each do |log|
126
- if File.stat(log).mtime < @retention
33
+ if File.stat(log).mtime < retention_time
127
34
  File.unlink(log) if @execute
128
35
  @logger.debug "Delete log file: #{log}" if @logger
129
36
  end
@@ -131,19 +38,19 @@ module NginxUtils
131
38
  end
132
39
 
133
40
  def restart
134
- if File.exists? @pid_file
135
- cmd = "kill -USR1 `cat #{@pid_file}`"
136
- @logger.debug "Nginx restart command: #{cmd}" if @logger
41
+ if File.exists? @params[:pid_file]
137
42
  if @execute
138
- if system(cmd)
43
+ begin
44
+ Process.kill(:USR1, File.read(@params[:pid_file]).to_i)
139
45
  @logger.info "Nginx restart is successfully" if @logger
140
- else
46
+ rescue => e
141
47
  @logger.error "Nginx restart failed" if @logger
142
- raise "Nginx restart failed" if @logger == false
48
+ @logger.error e if @logger
49
+ raise "Nginx restart failed"
143
50
  end
144
51
  end
145
52
  else
146
- @logger.warn "Pid file is not found. Do not restart nginx. (#{@pid_file})" if @logger
53
+ @logger.warn "Pid file is not found. Do not restart nginx." if @logger
147
54
  end
148
55
  end
149
56
 
@@ -156,8 +63,48 @@ module NginxUtils
156
63
  end
157
64
 
158
65
  private
159
- def debug(set=true)
160
- if set
66
+ def configure(options)
67
+ options = options.inject({}){|r,(k,v)| r.store(k.to_sym, v); r}
68
+ if @params.nil?
69
+ first = true
70
+ @params = default_params.merge(options)
71
+ flags = @params.keys
72
+ else
73
+ first = false
74
+ flags = options.select{|k,v| @params[k] != v}.keys
75
+ @params.merge!(options)
76
+ end
77
+
78
+ reglob = false
79
+
80
+ flags.each do |key|
81
+ case key
82
+ when :debug then config_debug
83
+ when :script_log then config_logger
84
+ when :log_level then config_loglevel
85
+ when :root_dir then reglob = true
86
+ when :target_logs then reglob = true
87
+ end
88
+ end
89
+
90
+ reglob_logs if reglob
91
+ end
92
+
93
+ def default_params
94
+ {
95
+ debug: false,
96
+ script_log: "/tmp/nginx_rotate.log",
97
+ log_level: :debug,
98
+ root_dir: "/usr/local/nginx",
99
+ target_logs: "*.log",
100
+ prefix: Time.now.strftime("%Y%m%d%H%M%S"),
101
+ retention: 90,
102
+ pid_file: "/usr/local/nginx/logs/nginx.pid"
103
+ }
104
+ end
105
+
106
+ def config_debug
107
+ if @params[:debug]
161
108
  @execute = false
162
109
  @logger = Logger.new(STDOUT)
163
110
  else
@@ -165,17 +112,17 @@ module NginxUtils
165
112
  end
166
113
  end
167
114
 
168
- def set_logger(log)
169
- case log
170
- when nil then @logger = Logger.new("/tmp/nginx_rotate.log")
171
- when false then @logger = false
172
- else @logger = Logger.new(log)
115
+ def config_logger
116
+ if @params[:script_log] == false
117
+ @logger = false
118
+ else
119
+ @logger = Logger.new(@params[:script_log])
173
120
  end
174
121
  end
175
122
 
176
- def set_log_level(level)
123
+ def config_loglevel
177
124
  if @logger
178
- case level
125
+ case @params[:log_level]
179
126
  when :fatal then @logger.level = Logger::FATAL
180
127
  when :error then @logger.level = Logger::ERROR
181
128
  when :warn then @logger.level = Logger::WARN
@@ -185,5 +132,10 @@ module NginxUtils
185
132
  end
186
133
  end
187
134
  end
135
+
136
+ def reglob_logs
137
+ @rename_logs = Dir.glob(File.join(@params[:root_dir], "**", @params[:target_logs]))
138
+ @delete_logs = Dir.glob(File.join(@params[:root_dir], "**", "#{@params[:target_logs]}.*"))
139
+ end
188
140
  end
189
141
  end
@@ -1,3 +1,3 @@
1
1
  module NginxUtils
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/nginx_utils.rb CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  require "logger"
4
4
  require "net/http"
5
+ require "thor"
5
6
 
6
7
  require "nginx_utils/version"
7
8
  require "nginx_utils/logrotate"
8
9
  require "nginx_utils/logreader"
9
10
  require "nginx_utils/status"
11
+ require "nginx_utils/cli"
data/nginx_utils.gemspec CHANGED
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "thor"
21
22
  spec.add_development_dependency "bundler", "~> 1.3"
22
23
  spec.add_development_dependency "rake"
23
24
  spec.add_development_dependency "rspec"
24
- spec.add_development_dependency "fakefs"
25
25
  end
@@ -0,0 +1,114 @@
1
+ # coding: utf-8
2
+
3
+ require "spec_helper"
4
+ require "stringio"
5
+
6
+ describe "NginxUtils::CLI" do
7
+ def capture(stream)
8
+ begin
9
+ stream = stream.to_s
10
+ eval "$#{stream} = StringIO.new"
11
+ yield
12
+ result = eval("$#{stream}").string
13
+ ensure
14
+ eval("$#{stream} = #{stream.upcase}")
15
+ end
16
+ result
17
+ end
18
+
19
+ describe "#status" do
20
+ let(:result) {
21
+ {
22
+ active_connections: 1,
23
+ accepts: 4,
24
+ handled: 5,
25
+ requests: 51,
26
+ reading: 1,
27
+ writing: 3,
28
+ waiting: 2
29
+ }
30
+ }
31
+
32
+ before(:each) {NginxUtils::Status.should_receive(:get).and_return(result)}
33
+
34
+ it "default output" do
35
+ args = ["status"]
36
+ expect(
37
+ capture(:stdout) {
38
+ NginxUtils::CLI.start(args)
39
+ }
40
+ ).to eq("Active Connections: \nAccepts: 4 Handled: 5 Requests: 51\nReading: 1 Writing: 3 Waiting: 2\n")
41
+ end
42
+
43
+ it "only value output" do
44
+ args = ["status", "--only_value"]
45
+ expect(
46
+ capture(:stdout) {
47
+ NginxUtils::CLI.start(args)
48
+ }
49
+ ).to eq("1\t4\t5\t51\t1\t3\t2\n")
50
+ end
51
+ end
52
+
53
+ describe "#logrotate" do
54
+ before(:each) do
55
+ @rotate = double("lotate mock")
56
+ @rotate.should_receive(:execute).and_return(true)
57
+ end
58
+
59
+ it "logrotate should be execute" do
60
+ NginxUtils::Logrotate.should_receive(:new).and_return(@rotate)
61
+ args = ["logrotate"]
62
+ NginxUtils::CLI.start(args)
63
+ end
64
+
65
+ it "debug option" do
66
+ options = {"debug" => true}
67
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
68
+ args = ["logrotate", "-d"]
69
+ NginxUtils::CLI.start(args)
70
+ end
71
+
72
+ it "script_log option" do
73
+ options = {"script_log" => "/var/log/nginx_rotate.log"}
74
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
75
+ args = ["logrotate", "--script_log", "/var/log/nginx_rotate.log"]
76
+ NginxUtils::CLI.start(args)
77
+ end
78
+
79
+ it "log_level option" do
80
+ options = {"log_level" => "warn"}
81
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
82
+ args = ["logrotate", "--log_level", "warn"]
83
+ NginxUtils::CLI.start(args)
84
+ end
85
+
86
+ it "root_dir option" do
87
+ options = {"root_dir" => "/usr/local/nginx_other"}
88
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
89
+ args = ["logrotate", "--root_dir", "/usr/local/nginx_other"]
90
+ NginxUtils::CLI.start(args)
91
+ end
92
+
93
+ it "target_logs option" do
94
+ options = {"target_logs" => "*_log"}
95
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
96
+ args = ["logrotate", "--target_logs", "*_log"]
97
+ NginxUtils::CLI.start(args)
98
+ end
99
+
100
+ it "retention option" do
101
+ options = {"retention" => "30"}
102
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
103
+ args = ["logrotate", "--retention", "30"]
104
+ NginxUtils::CLI.start(args)
105
+ end
106
+
107
+ it "pid_file option" do
108
+ options = {"pid_file" => "/var/run/nginx.pid"}
109
+ NginxUtils::Logrotate.should_receive(:new).with(options).and_return(@rotate)
110
+ args = ["logrotate", "--pid_file", "/var/run/nginx.pid"]
111
+ NginxUtils::CLI.start(args)
112
+ end
113
+ end
114
+ end
@@ -2,125 +2,130 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe NginxUtils do
6
- include FakeFS::SpecHelpers
7
-
8
- def create_log(format)
9
- log_dir = "/tmp"
10
- FileUtils.mkdir_p log_dir
11
-
12
- case format
13
- when :ltsv then
14
- line = "time:2013-05-19T08:13:14+00:00\thost:192.168.1.10\txff:-\tmethod:GET\tpath:/\tstatus:200\tua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31\treq_size:124\treq_time:0.007\tres_size:239\tbody_size:11\tapp_time:-\n"
15
- when :combined then
16
- line = "192.168.1.10 - - [19/May/2013:23:14:04 +0900] \"GET / HTTP/1.1\" 200 239 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31\"\n"
17
- else raise "format error"
18
- end
19
-
20
- File.open(File.join(log_dir, "access.log"), "w") do |f|
21
- 3.times {f.write line}
22
- end
5
+ describe "NginxUtils::Logreader" do
6
+ let!(:io_mock) do
7
+ io = double("io mock").as_null_object
8
+ File.stub(:open).and_return(io)
9
+ io
23
10
  end
24
11
 
25
- before(:each) do
26
- @log_file = "/tmp/access.log"
27
- @parser = /([0-9.]+)\s-\s([^\s]+)\s\[(.*?)\]\s"(.*?)"\s([0-9]+)\s([0-9]+)\s"(.*?)"\s"(.*?)"\s"(.*)".*/
28
- end
12
+ let(:access_log) {"/usr/local/nginx/logs/access.log"}
13
+ let(:parser) {/([0-9.]+)\s-\s([^\s]+)\s\[(.*?)\]\s"(.*?)"\s([0-9]+)\s([0-9]+)\s"(.*?)"\s"(.*?)".*/}
14
+ let(:reader) {NginxUtils::Logreader.new(access_log)}
29
15
 
30
- describe "Logreader" do
31
- describe "#initialize" do
32
- context "with default parameters" do
33
- before(:each) do
34
- create_log(:ltsv)
35
- @reader = NginxUtils::Logreader.new(@log_file)
36
- end
37
-
38
- it "specified file should be opened" do
39
- expect(@reader.instance_eval{@log}.path).to eq(@log_file)
40
- end
41
-
42
- it "default format should be ltsv" do
43
- expect(@reader.instance_eval{@format}).to eq(:ltsv)
44
- end
45
-
46
- it "default parser should be nil" do
47
- expect(@reader.instance_eval{@parser}).to eq(nil)
48
- end
16
+ describe "#initialize" do
17
+ context "with default parameters" do
18
+ it "specified file should be opened" do
19
+ File.should_receive(:open).with(access_log)
20
+ reader
49
21
  end
50
22
 
51
- context "with custom parameters" do
52
- before(:each) do
53
- create_log(:combined)
54
- end
55
-
56
- it "format should be specified parameter" do
57
- reader = NginxUtils::Logreader.new(@log_file, format: :combined)
58
- expect(reader.instance_eval{@format}).to eq(:combined)
59
- end
60
-
61
- it "parser should be specified parameter" do
62
- reader = NginxUtils::Logreader.new(@log_file, parser: @parser)
63
- expect(reader.instance_eval{@parser}).to eq(@parser)
64
- end
65
-
66
- it "format should be :custom if specified parser" do
67
- reader = NginxUtils::Logreader.new(@log_file, parser: @parser)
68
- expect(reader.instance_eval{@format}).to eq(:custom)
69
- end
70
-
71
- it "should create exception if parser is not Regexp instance" do
72
- expect(proc{NginxUtils::Logreader.new(@log_file, parser: "invalid parser")}).to raise_error("invalid argument")
73
- end
23
+ it "default format should be ltsv" do
24
+ expect(reader.instance_eval{@format}).to eq(:ltsv)
25
+ end
26
+
27
+ it "default parser should be nil" do
28
+ expect(reader.instance_eval{@parser}).to eq(nil)
74
29
  end
75
30
  end
76
31
 
77
- describe "#each" do
78
- context "with ltsv log" do
79
- it "return ltsv hash" do
80
- create_log(:ltsv)
81
- reader = NginxUtils::Logreader.new(@log_file)
82
- ltsv_hash = {
83
- time: "2013-05-19T08:13:14+00:00",
84
- host: "192.168.1.10",
85
- xff:"-",
86
- method: "GET",
87
- path: "/",
88
- status: "200",
89
- ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31",
90
- req_size: "124",
91
- req_time: "0.007",
92
- res_size: "239",
93
- body_size: "11",
94
- app_time: "-"
95
- }
96
- reader.each {|line| expect(line).to eq(ltsv_hash)}
97
- end
32
+ context "with custom parameters" do
33
+ it "format should be specified parameter" do
34
+ reader = NginxUtils::Logreader.new(access_log, format: :combined)
35
+ expect(reader.instance_eval{@format}).to eq(:combined)
98
36
  end
99
37
 
100
- context "with combined log" do
101
- it "return combined hash" do
102
- create_log(:combined)
103
- reader = NginxUtils::Logreader.new(@log_file, format: :combined)
104
- combined_hash = {
105
- remote_addr: "192.168.1.10",
106
- remote_user: "-",
107
- time_local: "19/May/2013:23:14:04 +0900",
108
- request: "GET / HTTP/1.1",
109
- status: "200",
110
- body_bytes_sent: "239",
111
- http_referer: "-",
112
- http_user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"
38
+ it "parser should be specified parameter" do
39
+ reader = NginxUtils::Logreader.new(access_log, parser: parser)
40
+ expect(reader.instance_eval{@parser}).to eq(parser)
41
+ end
42
+
43
+ it "format should be :custom if specified parser" do
44
+ reader = NginxUtils::Logreader.new(access_log, parser: parser)
45
+ expect(reader.instance_eval{@format}).to eq(:custom)
46
+ end
47
+
48
+ it "should create exception if parser is not Regexp instance" do
49
+ expect(
50
+ proc {
51
+ NginxUtils::Logreader.new(access_log, parser: "invalid parser")
113
52
  }
114
- reader.each {|line| expect(line).to eq(combined_hash)}
115
- end
116
-
117
- it "return unknown log if parse error" do
118
- create_log(:combined)
119
- File.open(@log_file, "w") {|f| f.write "unknown log"}
120
- reader = NginxUtils::Logreader.new(@log_file, format: :combined)
121
- reader.each {|line| expect(line).to eq({unknown: "unknown log"})}
122
- end
53
+ ).to raise_error("invalid argument")
123
54
  end
124
55
  end
125
56
  end
57
+
58
+ describe "#each" do
59
+ it "call parse method" do
60
+ io_mock.stub(:each).and_yield("log line\n")
61
+ NginxUtils::Logreader.any_instance.should_receive(:parse)
62
+ reader.each {|line| line}
63
+ end
64
+ end
65
+
66
+ describe "#parse" do
67
+ let(:ltsv_line) {"time:2013-05-19T08:13:14+00:00\thost:192.168.1.10\txff:-\tmethod:GET\tpath:/\tstatus:200\tua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31\treq_size:124\treq_time:0.007\tres_size:239\tbody_size:11\tapp_time:-\n"}
68
+ let(:combined_line) {"192.168.1.10 - - [19/May/2013:23:14:04 +0900] \"GET / HTTP/1.1\" 200 239 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31\"\n"}
69
+
70
+ it "ltsv format log" do
71
+ ltsv_hash = {
72
+ time: "2013-05-19T08:13:14+00:00",
73
+ host: "192.168.1.10",
74
+ xff:"-",
75
+ method: "GET",
76
+ path: "/",
77
+ status: "200",
78
+ ua: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31",
79
+ req_size: "124",
80
+ req_time: "0.007",
81
+ res_size: "239",
82
+ body_size: "11",
83
+ app_time: "-"
84
+ }
85
+ expect(reader.send(:parse, ltsv_line.chomp)).to eq(ltsv_hash)
86
+ end
87
+
88
+ it "combined format log" do
89
+ combined_hash = {
90
+ remote_addr: "192.168.1.10",
91
+ remote_user: "-",
92
+ time_local: "19/May/2013:23:14:04 +0900",
93
+ request: "GET / HTTP/1.1",
94
+ status: "200",
95
+ body_bytes_sent: "239",
96
+ http_referer: "-",
97
+ http_user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"
98
+ }
99
+ reader = NginxUtils::Logreader.new(access_log, format: :combined)
100
+ expect(reader.send(:parse, combined_line.chomp)).to eq(combined_hash)
101
+ end
102
+
103
+ it "return unknown log if parse error" do
104
+ unknown_line = "unknown log"
105
+ reader = NginxUtils::Logreader.new(access_log, format: :combined)
106
+ expect(reader.send(:parse, unknown_line)).to eq({unknown: unknown_line})
107
+ end
108
+
109
+ it "custom format parser" do
110
+ custom_hash = [
111
+ [
112
+ "192.168.1.10",
113
+ "-",
114
+ "19/May/2013:23:14:04 +0900",
115
+ "GET / HTTP/1.1",
116
+ "200",
117
+ "239",
118
+ "-",
119
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"
120
+ ]
121
+ ]
122
+ reader = NginxUtils::Logreader.new(access_log, parser: parser)
123
+ expect(reader.send(:parse, combined_line.chomp)).to eq(custom_hash)
124
+ end
125
+
126
+ it "create exception if unknown format" do
127
+ reader = NginxUtils::Logreader.new(access_log, format: :unknown)
128
+ expect(proc{reader.send(:parse, combined_line.chomp)}).to raise_error("format error")
129
+ end
130
+ end
126
131
  end