sms-logparser 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|