sms-logparser 0.8.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee62704f6c086eca49b8be2a23d8d553bb2ecdc5
4
- data.tar.gz: fe95f14c8bc3733ba2046d8501ff15fbf900013f
3
+ metadata.gz: 9f876436c72457987cb31430a76668f0613cde56
4
+ data.tar.gz: cb5a9b5a5b6d4d2a09bded36130cbe557492dc10
5
5
  SHA512:
6
- metadata.gz: 0da2eeb8730a5c9efea1379c02feeacc9e29c145ca29ba8c9e6e390503042c7b3a56833c792f68e9d505bcd296c7ad08c2fc8a2af0b490d68fdc97dc409a7048
7
- data.tar.gz: b564ad5f22a5797ed5982d7ba9855526986d5e495fe8f1be7b327e8e2f501f5ca2b99f7c8f3934c1a998779563ecef4be65b6e49acb9d3084f91fd5d52988d31
6
+ metadata.gz: 1c258366166a28499e44ab7867d7a6b4e6cbdfca5a837bd6910322cd8ef8c022127518539954fea02303cc7d22d01708b3a1a2951dc69811e8db37a053ca1825
7
+ data.tar.gz: b5b2c2199aa31028db755f46cdcaf2a408232a8e6cdd0359b9084ff399db4645f31e3bbbeb97419cda1a7f6445322b96d0b15f43e3060150826f7041a100d59c
data/lib/sms-logparser.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require "rubygems" # ruby1.9 doesn't "require" it though
2
2
  require "thor"
3
- require 'mysql2'
4
- require 'faraday'
3
+ require "mysql2"
4
+ require "faraday"
5
5
 
6
6
  require "sms-logparser/version"
7
7
  require "sms-logparser/mysql"
8
8
  require "sms-logparser/parser"
9
9
  require "sms-logparser/api"
10
+ require "sms-logparser/app_logger"
10
11
  require "sms-logparser/cli"
@@ -4,25 +4,26 @@ module SmsLogparser
4
4
 
5
5
  def initialize(options)
6
6
  @options = options
7
- @base_url = URI(@options[:api_base_url] || 'http://localhost:8080/creator/rest/')
7
+ @base_url = URI(@options[:api_base_url] || 'http://localhost:8080/creator/rest/')
8
8
  @url = @base_url.to_s.chomp(@base_url.path)
9
+ @base_path = (@base_url.path << "/").squeeze('/')
9
10
  @accepted_responses = parse_status_codes(options[:accepted_api_responses]) || [200]
10
11
  @connection = connection
11
12
  end
12
13
 
13
14
  def send(data)
14
15
  requests = []
15
- base_path = @base_url.path + [data[:customer_id], data[:author_id], data[:project_id]].join('/')
16
+ path = @base_path << [data[:customer_id], data[:author_id], data[:project_id]].join('/')
16
17
  unless data[:file] =~ /.*\.m3u8$/
17
18
  requests << {
18
19
  url: @url,
19
- uri: [base_path, data[:traffic_type], data[:bytes]].join('/'),
20
+ uri: [path, data[:traffic_type], data[:bytes]].join('/'),
20
21
  }
21
22
  end
22
23
  if data[:visitor_type]
23
24
  requests << {
24
25
  url: @url,
25
- uri: [base_path, data[:visitor_type], 1].join('/')
26
+ uri: [path, data[:visitor_type], 1].join('/')
26
27
  }
27
28
  end
28
29
  unless @options[:simulate]
@@ -45,9 +46,11 @@ module SmsLogparser
45
46
  private
46
47
 
47
48
  def connection
48
- connection = Faraday.new(url: @url) do |faraday|
49
+ connection = Faraday.new(url: @url, request: {timeout: 5}) do |faraday|
49
50
  faraday.request :url_encoded
50
- faraday.response :logger if @options[:debug]
51
+ if @options[:debug]
52
+ faraday.use Faraday::Response::Logger, SmsLogparser::AppLogger.instance
53
+ end
51
54
  faraday.adapter :net_http_persistent
52
55
  end
53
56
  connection.headers[:user_agent] = "sms-logparser v#{SmsLogparser::VERSION}"
@@ -0,0 +1,24 @@
1
+ module SmsLogparser
2
+ require 'logger'
3
+ require 'singleton'
4
+
5
+ class AppLogger < Logger
6
+ include Singleton
7
+
8
+ def initialize
9
+ @level = INFO
10
+ @logdev = STDOUT
11
+ @progname ||= 'sms-logparser'
12
+ @formatter = proc do |severity, datetime, progname, msg|
13
+ "#{datetime} #{severity} [sms-logparser v#{SmsLogparser::VERSION}] #{msg}\n"
14
+ end
15
+ end
16
+
17
+ def set_log_device(log_file_path = nil)
18
+ device = log_file_path ? File.open(log_file_path, "a") : STDOUT
19
+ @logdev = Logger::LogDevice.new(device)
20
+ self
21
+ end
22
+
23
+ end
24
+ end
@@ -9,21 +9,12 @@ module SmsLogparser
9
9
  aliases: %w(-c),
10
10
  desc: "Configuration file for default options"
11
11
 
12
- class_option :mysql_host,
13
- aliases: %w(-h),
14
- desc: "MySQL host"
15
-
16
- class_option :mysql_user,
17
- aliases: %w(-u),
18
- desc: "MySQL user (Default: root)"
19
-
20
- class_option :mysql_password,
21
- aliases: %w(-p),
22
- desc: "MySQL password"
23
-
24
- class_option :mysql_db,
25
- aliases: %w(-d),
26
- desc: "MySQL database (Default: Syslog)"
12
+ class_option :debug, type: :boolean, desc: "Show debug output"
13
+ class_option :logfile, desc: "Path to the logfile (Default: STDOUT)"
14
+ class_option :mysql_host, aliases: %w(-h), desc: "MySQL host"
15
+ class_option :mysql_user, aliases: %w(-u), desc: "MySQL user (Default: root)"
16
+ class_option :mysql_password, aliases: %w(-p), desc: "MySQL password"
17
+ class_option :mysql_db, aliases: %w(-d), desc: "MySQL database (Default: Syslog)"
27
18
 
28
19
  desc "version", "Print sms-logparser version number"
29
20
  def version
@@ -32,45 +23,29 @@ module SmsLogparser
32
23
  map %w(-v --version) => :version
33
24
 
34
25
  desc "parse", "Check the database for pcache logs and send them to the SMS-API"
35
- option :api_base_url,
36
- aliases: %w(-a),
26
+ option :api_base_url, aliases: %w(-a),
37
27
  desc: "Base path of the SMS API (Default: http://localhost:8080/creator/rest/)"
38
- option :api_key,
39
- aliases: %w(-k),
40
- desc: "SMS API Key"
41
- option :simulate,
42
- type: :boolean,
43
- default: false,
44
- aliases: %w(-s),
28
+ option :api_key, aliases: %w(-k), desc: "SMS API Key"
29
+ option :simulate, type: :boolean, aliases: %w(-s),
45
30
  desc: "Dry run without submitting any data"
46
- option :verbose,
47
- type: :boolean,
48
- default: false,
49
- aliases: %w(-v),
50
- desc: "Verbose output"
51
- option :limit,
52
- type: :numeric,
53
- aliases: %w(-l),
54
- desc: "Limit the number of entries to query"
55
- option :debug,
56
- type: :boolean,
57
- default: false,
58
- desc: "Show debug output"
59
- option :accepted_api_responses,
60
- type: :array,
31
+ option :verbose, type: :boolean, aliases: %w(-v), desc: "Verbose output"
32
+ option :limit, type: :numeric, aliases: %w(-l), desc: "Limit the number of entries to query"
33
+ option :accepted_api_responses, type: :array, aliases: %w(-r),
61
34
  desc: "API HTTP responses which are accepted (Default: only accept 200)."
62
35
  def parse
63
- say "Starting the parser...", :green
36
+ start_message = "Parser started"
37
+ start_message += options[:simulate] ? " in simulation mode." : "."
38
+ logger.info(start_message)
64
39
  mysql = Mysql.new(options)
65
40
  if !options[:simulate] && mysql.parser_running?
66
- say "Exit. Another instance of the parser is already running.", :yellow
41
+ logger.warn("Exit. Another instance of the parser is already running.")
67
42
  exit
68
43
  end
69
44
  state = {
70
45
  last_event_id: mysql.get_last_parse_id,
71
46
  match_count: 0,
72
47
  status: STATUS[:running],
73
- run_at: Time.now,
48
+ started_at: Time.now,
74
49
  run_time: 0.0
75
50
  }
76
51
  state = mysql.start_run(state) unless options[:simulate]
@@ -81,45 +56,42 @@ module SmsLogparser
81
56
  if data
82
57
  requests = api.send(data)
83
58
  state[:match_count] += 1
84
- verbose_parser_output(data, requests, entry['ID']) if options[:verbose]
59
+ verbose_parser_output(entry['ID'], data, requests) if options[:verbose]
60
+ state[:last_event_id] = entry['ID']
85
61
  end
86
62
  end
87
- state[:last_event_id] = entry['ID']
88
63
  end
89
64
  end
90
65
  state[:status] = STATUS[:ok]
91
66
  rescue => e
92
- say "Error: #{e.message}", :red
93
- say "Aborting parser run...", :red
67
+ logger.error("#{e.message}. Aborting the parser run.")
94
68
  say(e.backtrace.join("\n"), :yellow) if options[:debug]
95
69
  state[:status] = STATUS[:api_error] if state
96
70
  ensure
97
71
  begin
98
72
  if mysql && state
99
- state[:run_time] = (Time.now - state[:run_at]).round(2)
73
+ state[:run_time] = (Time.now - state[:started_at]).round(2)
100
74
  if state[:id]
101
75
  mysql.write_parse_result(state) unless options[:simulate]
102
76
  end
103
- print_parse_results(state)
77
+ log_parse_results(state)
104
78
  end
105
79
  rescue => e
106
- say "Error: #{e.message}", :red
80
+ logger.fatal(e.message)
107
81
  say(e.backtrace.join("\n"), :yellow) if options[:debug]
108
82
  end
109
83
  end
110
84
 
111
85
  desc "history", "List the last paser runs"
112
- option :results,
113
- type: :numeric,
114
- default: 10,
115
- aliases: %w(-n),
86
+ option :results, type: :numeric, default: 10, aliases: %w(-n),
116
87
  desc: "Number of results to display"
117
88
  def history
118
89
  runs = Mysql.new(options).last_runs(options[:results])
119
90
  if runs && runs.size > 0
120
- table = [%w(run_at count last_id status run_time)]
91
+ table = [%w(id started_at count last_id status run_time)]
121
92
  runs.to_a.reverse.each do |run|
122
93
  table << [
94
+ run['id'],
123
95
  run['run_at'].strftime('%d.%d.%Y %T'),
124
96
  run['match_count'],
125
97
  run['last_event_id'],
@@ -132,50 +104,46 @@ module SmsLogparser
132
104
  say "No parser runs found in the database."
133
105
  end
134
106
  rescue => e
135
- say "Error: #{e.message}", :red
136
- exit 1
107
+ logger.fatal(e.message)
108
+ say(e.backtrace.join("\n"), :yellow) if options[:debug]
137
109
  end
138
110
 
139
111
  desc "setup", "Create the parser table to track the last logs parsed"
140
- option :force,
141
- type: :boolean,
142
- default: false,
143
- aliases: %w(-f),
112
+ option :force, type: :boolean, default: false, aliases: %w(-f),
144
113
  desc: "Drop an existing table if it exists"
145
114
  def setup
146
115
  case Mysql.new(options).create_parser_table(options[:force])
147
116
  when 0
148
- say "OK, table created.", :green
117
+ logger.info("Created database table.")
149
118
  when 1
150
- say "Table already exists.", :yellow
119
+ logger.warn("Table already exists.")
120
+ when 2
121
+ logger.info("Recreated database tables.")
151
122
  end
152
123
  rescue => e
153
- say "Error: #{e.message}", :red
154
- exit 1
124
+ logger.fatal(e.message)
125
+ say(e.backtrace.join("\n"), :yellow) if options[:debug]
155
126
  end
156
127
 
157
128
  no_commands do
158
- def verbose_parser_output(data, requests, entry_id)
159
- say "ID:\t", :cyan
160
- say entry_id
161
- say "URL:\t", :cyan
162
- say requests.map {|req| "#{req[:url]}#{req[:uri]} (Status: #{req[:status] || 'n/a'})"}.join("\n\t")
163
- say "Data:\t", :cyan
164
- say data.map{|k,v| "#{k}:\t#{v || '-'}"}.join("\n\t") || "\n"
165
- puts
166
- puts "-" * 100
167
- puts
129
+ def logger
130
+ SmsLogparser::AppLogger.instance.set_log_device(options[:logfile])
131
+ end
132
+
133
+ def verbose_parser_output(entry_id, data, requests)
134
+ logger.info {
135
+ "parsing data for #{entry_id} (#{data.map{|k,v| "#{k}=\"#{v || '-'}\""}.join(" ") || ''})"
136
+ }
137
+ logger.info {
138
+ "parser urls for entry #{entry_id} (#{requests.map {|req| "#{req[:url]}#{req[:uri]}"}.join(" ")})"
139
+ }
168
140
  end
169
141
 
170
- def print_parse_results(res)
171
- say "Started:\t", :cyan
172
- say res[:run_at].strftime('%d.%d.%Y %T')
173
- say "Runtime:\t", :cyan
174
- say "#{res[:run_time]}s"
175
- say "Status:\t\t", :cyan
176
- say STATUS.key(res[:status]).upcase
177
- say("Events #{options[:simulate] ? "found" : "sent"}:\t", :cyan)
178
- say res[:match_count]
142
+ def log_parse_results(res)
143
+ res = res.reject {|k,v| %w(:id :run_at).include? k}
144
+ message = "Parser #{options[:simulate] ? 'simulation' : 'run'} ended."
145
+ message += " (" + res.map {|k,v| "#{k}=\"#{v}\""}.join(' ') + ")"
146
+ logger.info(message)
179
147
  end
180
148
 
181
149
  def options
@@ -24,8 +24,9 @@ module SmsLogparser
24
24
  end
25
25
 
26
26
  def create_parser_table(force = false)
27
+ status = 0
27
28
  if force
28
- drop_parser_table
29
+ status = drop_parser_table ? 2 : 0
29
30
  elsif parser_table_exists?
30
31
  return 1
31
32
  end
@@ -40,7 +41,7 @@ module SmsLogparser
40
41
  INDEX `last_event_id_I1` (`last_event_id`)
41
42
  )"
42
43
  )
43
- return 0
44
+ status
44
45
  end
45
46
 
46
47
  def parser_running?(running_state = 3)
@@ -57,7 +58,7 @@ module SmsLogparser
57
58
  client.query(
58
59
  "INSERT INTO sms_logparser_runs (run_at, status)\
59
60
  VALUES (\
60
- '#{options[:run_at].strftime("%Y-%m-%d %H:%M:%S")}',\
61
+ '#{options[:started_at].strftime("%Y-%m-%d %H:%M:%S")}',\
61
62
  #{options[:status]}\
62
63
  )"
63
64
  )
@@ -131,8 +132,9 @@ module SmsLogparser
131
132
  end
132
133
 
133
134
  def drop_parser_table
134
- return nil unless parser_table_exists?
135
+ return false unless parser_table_exists?
135
136
  client.query("DROP TABLE sms_logparser_runs")
137
+ true
136
138
  end
137
139
 
138
140
  end # class
@@ -1,3 +1,3 @@
1
1
  module SmsLogparser
2
- VERSION = "0.8.4"
2
+ VERSION = "0.9.0"
3
3
  end
data/spec/cli_spec.rb CHANGED
@@ -19,7 +19,7 @@ describe SmsLogparser::Cli do
19
19
  out, err = capture_io do
20
20
  parser.setup
21
21
  end
22
- out.must_match /OK.*/
22
+ out.must_match /.*Created database table./
23
23
  end
24
24
 
25
25
  it "can parse a log database and find matches" do
@@ -31,7 +31,7 @@ describe SmsLogparser::Cli do
31
31
  parser.setup
32
32
  parser.parse
33
33
  end
34
- out.must_match /\s+10$/
34
+ out.must_match /.*match_count=10.*/
35
35
  end
36
36
 
37
37
  # it "skips over already parsed logs" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sms-logparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.4
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - niwo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-08 00:00:00.000000000 Z
11
+ date: 2014-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -125,6 +125,7 @@ files:
125
125
  - bin/sms-logparser
126
126
  - lib/sms-logparser.rb
127
127
  - lib/sms-logparser/api.rb
128
+ - lib/sms-logparser/app_logger.rb
128
129
  - lib/sms-logparser/cli.rb
129
130
  - lib/sms-logparser/mysql.rb
130
131
  - lib/sms-logparser/parser.rb