sms-logparser 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +9 -2
- data/lib/sms-logparser/api.rb +13 -11
- data/lib/sms-logparser/cli.rb +29 -18
- data/lib/sms-logparser/mysql.rb +1 -0
- data/lib/sms-logparser/parser.rb +29 -8
- data/lib/sms-logparser/version.rb +1 -1
- data/spec/cli_spec.rb +2 -2
- data/spec/parser_spec.rb +82 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 484db0ec68fb533d509b336f6d5258947a1550cb
|
4
|
+
data.tar.gz: c826cb94003ff3beea5b579e1967a4f3a45cd548
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1638d239b7bd9ef872f92b2c87271de78eb6ffe46b187609c132607adb7921f2637d0605f3a101c9ae808678b0fe2f995d4dcaff5d868c5e145d8e50f019441
|
7
|
+
data.tar.gz: 53b8660b214c5a8cd97de7160372b8b5082a5b13c851db48702aae481f0e2151de7118b9fb4024e6979d4c33b318f33988b108625248842ef40e8c7669b0a210
|
data/README.md
CHANGED
@@ -20,11 +20,11 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
Create the database table to track which logs have been parsed:
|
22
22
|
|
23
|
-
$ sms-logparser
|
23
|
+
$ sms-logparser setup
|
24
24
|
|
25
25
|
Make a test run:
|
26
26
|
|
27
|
-
$ sms-logparser parse --simulate
|
27
|
+
$ sms-logparser parse --simulate --verbose
|
28
28
|
|
29
29
|
## Usage
|
30
30
|
|
@@ -40,6 +40,13 @@ Show the last parser runs:
|
|
40
40
|
|
41
41
|
$ sms-logparser last_runs
|
42
42
|
|
43
|
+
# Development
|
44
|
+
|
45
|
+
- check out the git repo (git clone ...)
|
46
|
+
- implement your changes
|
47
|
+
- run the tests `rake test`
|
48
|
+
- bump the version number commit your changes and release a new version of the gem `rake release`
|
49
|
+
|
43
50
|
## Contributing
|
44
51
|
|
45
52
|
1. Fork it
|
data/lib/sms-logparser/api.rb
CHANGED
@@ -6,20 +6,22 @@ module SmsLogparser
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def send(data)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
base_url = "#{@options[:api_base_path]}/"
|
10
|
+
base_url += "#{data[:customer_id]}/"
|
11
|
+
base_url += "#{data[:author_id]}/"
|
12
|
+
base_url += "#{data[:project_id]}"
|
13
|
+
urls = ["#{base_url}/#{data[:traffic_type]}/#{data[:bytes]}"]
|
14
|
+
urls << "#{base_url}/#{data[:visitor_type]}/1" if data[:visitor_type]
|
15
15
|
unless @options[:simulate]
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
urls.each do |url|
|
17
|
+
begin
|
18
|
+
RestClient.get(url)
|
19
|
+
rescue
|
20
|
+
raise "Can't send request to #{url}"
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
|
-
|
24
|
+
urls
|
23
25
|
end
|
24
26
|
|
25
27
|
end # class
|
data/lib/sms-logparser/cli.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
module SmsLogparser
|
2
2
|
class Cli < Thor
|
3
3
|
|
4
|
-
class_option :mysql_host, :default => 'localhost'
|
5
|
-
class_option :mysql_user, :default => 'root'
|
6
|
-
class_option :
|
4
|
+
class_option :mysql_host, :default => 'localhost', aliases: %w(-h)
|
5
|
+
class_option :mysql_user, :default => 'root', aliases: %w(-u)
|
6
|
+
class_option :mysql_password, aliases: %w(-p)
|
7
|
+
class_option :mysql_db, :default => 'Syslog', aliases: %w(-d)
|
7
8
|
|
8
9
|
desc "version", "print cloudstack-cli version number"
|
9
10
|
def version
|
@@ -12,8 +13,9 @@ module SmsLogparser
|
|
12
13
|
map %w(-v --version) => :version
|
13
14
|
|
14
15
|
desc "parse", "Check the database for pcache logs and send them to SMS"
|
15
|
-
option :api_base_path, :default => 'http://dev.simplex.tv/creator/rest'
|
16
|
-
option :simulate, :type => :boolean, :default => false
|
16
|
+
option :api_base_path, :default => 'http://dev.simplex.tv/creator/rest', aliases: %w(-a)
|
17
|
+
option :simulate, :type => :boolean, :default => false, aliases: %w(-s)
|
18
|
+
option :verbose, :type => :boolean, :default => false, aliases: %w(-v)
|
17
19
|
def parse
|
18
20
|
start_time = Time.now
|
19
21
|
count = 0
|
@@ -23,18 +25,27 @@ module SmsLogparser
|
|
23
25
|
api = Api.new(options)
|
24
26
|
last_id = mysql.get_last_parse_id
|
25
27
|
entries.each do |entry|
|
26
|
-
if Parser.match(entry)
|
28
|
+
if Parser.match(entry['Message'])
|
27
29
|
data = Parser.extract_data_from_msg(entry['Message'])
|
28
|
-
|
30
|
+
begin
|
31
|
+
urls = api.send(data)
|
32
|
+
rescue => e
|
33
|
+
say "Error: #{e.message}", :red
|
34
|
+
say "Aborting parser run...", :red
|
35
|
+
break
|
36
|
+
end
|
29
37
|
last_id = entry['ID']
|
30
38
|
count += 1
|
31
|
-
|
39
|
+
verbose_parser_output(data, urls, entry) if options[:verbose]
|
32
40
|
end
|
33
41
|
end
|
34
42
|
mysql.write_parse_result(last_id, count) unless options[:simulate]
|
35
|
-
|
36
|
-
|
37
|
-
|
43
|
+
say "Started:\t", :cyan
|
44
|
+
say start_time.strftime('%d.%d.%Y %T')
|
45
|
+
say "Runtime:\t", :cyan
|
46
|
+
say "#{(Time.now - start_time).round(2)}s"
|
47
|
+
options[:simulate] ? say("Events found:\t", :cyan) : say("Events sent:\t", :cyan)
|
48
|
+
say count
|
38
49
|
rescue => e
|
39
50
|
say "Error: #{e.message}", :red
|
40
51
|
end
|
@@ -73,14 +84,14 @@ module SmsLogparser
|
|
73
84
|
end
|
74
85
|
|
75
86
|
no_commands do
|
76
|
-
def
|
77
|
-
|
78
|
-
say "Message ID: ", :green
|
87
|
+
def verbose_parser_output(data, urls, entry)
|
88
|
+
say "ID:\t", :cyan
|
79
89
|
say entry['ID']
|
80
|
-
say "URL
|
81
|
-
say
|
82
|
-
say "Data
|
83
|
-
say data
|
90
|
+
say "URL:\t", :cyan
|
91
|
+
say urls.join("\n\t")
|
92
|
+
say "Data:\t", :cyan
|
93
|
+
say data.map{|k,v| "#{k}:\t#{v}"}.join("\n\t")
|
94
|
+
puts "-" * 100
|
84
95
|
puts
|
85
96
|
end
|
86
97
|
end
|
data/lib/sms-logparser/mysql.rb
CHANGED
data/lib/sms-logparser/parser.rb
CHANGED
@@ -1,34 +1,55 @@
|
|
1
1
|
module SmsLogparser
|
2
2
|
class Parser
|
3
3
|
|
4
|
-
def self.extract_data_from_msg(
|
5
|
-
m =
|
4
|
+
def self.extract_data_from_msg(message)
|
5
|
+
m = message.match /\/content\/(\d+)\/(\d+)\/(\d+)\/(\w+\.\w+)\s.*\"\s\d+\s(\d+).+"(.*)"$/
|
6
6
|
raise "No match found." unless m
|
7
|
+
traffic_type = Parser.get_traffic_type(m[6])
|
8
|
+
visitor_type = Parser.get_visitor_type(traffic_type, m[4])
|
7
9
|
data = {
|
8
10
|
:customer_id => m[1],
|
9
11
|
:author_id => m[2],
|
10
12
|
:project_id => m[3],
|
11
|
-
:
|
12
|
-
:traffic_type => Parser.get_traffic_type(m[4]),
|
13
|
+
:file => m[4],
|
13
14
|
:bytes => m[5],
|
14
|
-
:user_agent => m[6]
|
15
|
+
:user_agent => m[6],
|
16
|
+
:traffic_type => traffic_type,
|
17
|
+
:visitor_type => visitor_type
|
15
18
|
}
|
16
19
|
end
|
17
20
|
|
18
|
-
def self.match(
|
19
|
-
|
21
|
+
def self.match(message)
|
22
|
+
message =~ /\/content\/.*\.(f4v|flv|mp4|mp3|ts|m3u8) .* (200|206)/
|
20
23
|
end
|
21
24
|
|
25
|
+
# see https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
|
26
|
+
# for mobile browser detection
|
22
27
|
def self.get_traffic_type(user_agent)
|
23
28
|
case user_agent
|
24
29
|
when /.*(iTunes).*/
|
25
30
|
"TRAFFIC_PODCAST"
|
26
|
-
when /.*(IEMobile|Mobile Safari|iPhone|iPod|iPad).*/
|
31
|
+
when /.*(Mobi|IEMobile|Mobile Safari|iPhone|iPod|iPad|Android|BlackBerry|Opera Mini).*/
|
27
32
|
"TRAFFIC_MOBILE"
|
28
33
|
else
|
29
34
|
"TRAFFIC_WEBCAST"
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
38
|
+
def self.get_visitor_type(traffic_type, file)
|
39
|
+
return "VISITORS_MOBILE" if file == 'index.m3u8'
|
40
|
+
case traffic_type
|
41
|
+
when "TRAFFIC_PODCAST"
|
42
|
+
"VISITORS_PODCAST"
|
43
|
+
when "TRAFFIC_MOBILE"
|
44
|
+
if File.extname(file) != ".ts"
|
45
|
+
"VISITORS_MOBILE"
|
46
|
+
else
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
else
|
50
|
+
"VISITORS_WEBCAST"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
33
54
|
end # class
|
34
55
|
end # module
|
data/spec/cli_spec.rb
CHANGED
@@ -25,7 +25,7 @@ describe SmsLogparser::Cli do
|
|
25
25
|
TestHelper.sms_logparser.setup
|
26
26
|
parser.parse
|
27
27
|
end
|
28
|
-
out.must_match
|
28
|
+
out.must_match /\s+10$/
|
29
29
|
end
|
30
30
|
|
31
31
|
it "skips over already parsed logs" do
|
@@ -37,7 +37,7 @@ describe SmsLogparser::Cli do
|
|
37
37
|
parser.parse
|
38
38
|
parser.parse
|
39
39
|
end
|
40
|
-
out.must_match
|
40
|
+
out.must_match /\s+0$/
|
41
41
|
end
|
42
42
|
|
43
43
|
it "lists parser runs" do
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SmsLogparser::Parser do
|
4
|
+
|
5
|
+
%w(f4v flv mp4 mp3 ts m3u8).each do |extension|
|
6
|
+
it "matches #{extension} files" do
|
7
|
+
SmsLogparser::Parser.match(
|
8
|
+
"GET /content/2/719/54986/file.#{extension} HTTP/1.1\" 200 6741309 "
|
9
|
+
).wont_be_nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
%w(jpg js css m4a docx).each do |extension|
|
14
|
+
it "does not matche #{extension} files" do
|
15
|
+
SmsLogparser::Parser.match(
|
16
|
+
"GET /content/2/719/54986/file.#{extension} HTTP/1.1\" 200 6741309 "
|
17
|
+
).must_be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
%w(200 206).each do |status|
|
22
|
+
it "does match status code #{status}" do
|
23
|
+
SmsLogparser::Parser.match(
|
24
|
+
"GET /content/2/719/54986/file.mp4 HTTP/1.1\" #{status} 50000 "
|
25
|
+
).wont_be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
%w(404 500 304).each do |status|
|
30
|
+
it "does not match status code #{status}" do
|
31
|
+
SmsLogparser::Parser.match(
|
32
|
+
"GET /content/2/719/54986/file.mp4 HTTP/1.1\" #{status} 50000 "
|
33
|
+
).must_be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
%w(contents public index CONTENT).each do |dir|
|
38
|
+
it "does not match directories other than /content" do
|
39
|
+
SmsLogparser::Parser.match(
|
40
|
+
"GET /#{dir}/2/719/54986/file.mp4 HTTP/1.1\" 200 50000 "
|
41
|
+
).must_be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
[
|
46
|
+
"Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10",
|
47
|
+
"Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0",
|
48
|
+
"Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50",
|
49
|
+
"Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047",
|
50
|
+
"Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)",
|
51
|
+
"Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
|
52
|
+
].each do |mobile_agent|
|
53
|
+
it "traffic type for mobile user agents is TRAFFIC_MOBILE (#{mobile_agent})" do
|
54
|
+
SmsLogparser::Parser.get_traffic_type(mobile_agent).must_equal "TRAFFIC_MOBILE"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set visitor_type to VISITORS_MOBILE for index.m3u8 files" do
|
59
|
+
SmsLogparser::Parser.get_visitor_type(
|
60
|
+
"TRAFFIC_PODCAST", "index.m3u8"
|
61
|
+
).must_equal "VISITORS_MOBILE"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should NOT set visitor_type to VISITORS_MOBILE for TRAFFIC_MOBILE and .ts files" do
|
65
|
+
SmsLogparser::Parser.get_visitor_type(
|
66
|
+
"TRAFFIC_MOBILE", "file.ts"
|
67
|
+
).must_be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should set visitor_type to VISITORS_MOBILE for TRAFFIC_MOBILE and file not .ts" do
|
71
|
+
SmsLogparser::Parser.get_visitor_type(
|
72
|
+
"TRAFFIC_MOBILE", "file.mp3"
|
73
|
+
).must_equal "VISITORS_MOBILE"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should set visitor_type to VISITORS_PODCAST for TRAFFIC_PODCAST" do
|
77
|
+
SmsLogparser::Parser.get_visitor_type(
|
78
|
+
"TRAFFIC_PODCAST", "file.mp4"
|
79
|
+
).must_equal "VISITORS_PODCAST"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
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.
|
4
|
+
version: 0.2.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-03-
|
11
|
+
date: 2014-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- lib/sms-logparser/version.rb
|
103
103
|
- sms-logparser.gemspec
|
104
104
|
- spec/cli_spec.rb
|
105
|
+
- spec/parser_spec.rb
|
105
106
|
- spec/spec_helper.rb
|
106
107
|
homepage: https://github.com/swisstxt/sms-logparser
|
107
108
|
licenses:
|
@@ -129,4 +130,5 @@ specification_version: 4
|
|
129
130
|
summary: SMS Logparser
|
130
131
|
test_files:
|
131
132
|
- spec/cli_spec.rb
|
133
|
+
- spec/parser_spec.rb
|
132
134
|
- spec/spec_helper.rb
|