sentry_fs 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.
- checksums.yaml +7 -0
- data/bin/sentry_fs +79 -0
- data/lib/sentry_fs.rb +64 -0
- data/sentry_fs.gemspec +23 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/test_sentry_fs.rb +83 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a7385144932acf7cdd009fbb6713e7527cb67d2
|
4
|
+
data.tar.gz: 347b2e26ade28383bc1ae89c9ac46dce2d178eed
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07050064749397a234c45643b51f0b9f99139fa4d67d21380cce86bf317a7e6b78eceddf899cf3fbf55ab633fc9416d96a6f90f569ff50f0d814e5e2a5396411
|
7
|
+
data.tar.gz: 5f7d27f2ed638e61440972f73179cf82ee4b15401482f83671ef276361797f4f9ccd2e89d00e215494d7fb0c5d0cf734de03913faa8e2201d05b34a7049aa2c0
|
data/bin/sentry_fs
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "logger"
|
5
|
+
require "raven"
|
6
|
+
require "file/tail"
|
7
|
+
require "sentry_fs"
|
8
|
+
|
9
|
+
logger = Logger.new(STDOUT)
|
10
|
+
options = {}
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: sentry_fs [options]"
|
14
|
+
|
15
|
+
opts.on("--fslog PATH", "PATH to FreeSWITCH log") {|path|
|
16
|
+
options[:fs_log] = path
|
17
|
+
}
|
18
|
+
|
19
|
+
opts.on("--dsn DSN", "Sentry DSN") {|dsn|
|
20
|
+
options[:dsn] = dsn
|
21
|
+
}
|
22
|
+
|
23
|
+
opts.on("--log PATH", "PATH to sentry_fs log") {|path|
|
24
|
+
logger = Logger.new(path)
|
25
|
+
}
|
26
|
+
|
27
|
+
opts.on("--daemon", "Run in background") {|daemon|
|
28
|
+
options[:daemon] = daemon
|
29
|
+
}
|
30
|
+
|
31
|
+
opts.on("--pidfile PATH", "PATH to pidfile") {|path|
|
32
|
+
options[:pidfile] = path
|
33
|
+
}
|
34
|
+
end.parse!
|
35
|
+
|
36
|
+
if !options[:fs_log]
|
37
|
+
$stderr.puts "--fslog required"
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
|
41
|
+
if !options[:dsn]
|
42
|
+
$stderr.puts "--dsn required"
|
43
|
+
exit 2
|
44
|
+
end
|
45
|
+
|
46
|
+
if !File.exists?(options[:fs_log])
|
47
|
+
$stderr.puts "#{options[:fs_log]} does not exist"
|
48
|
+
exit 3
|
49
|
+
end
|
50
|
+
|
51
|
+
if options[:daemon]
|
52
|
+
Process.daemon(nochdir=true)
|
53
|
+
end
|
54
|
+
|
55
|
+
if options[:pidfile]
|
56
|
+
File.open(options[:pidfile], "w") {|f| f.write(Process.pid)}
|
57
|
+
end
|
58
|
+
|
59
|
+
Raven.configure do |config|
|
60
|
+
config.dsn = options[:dsn]
|
61
|
+
config.logger = logger
|
62
|
+
config.current_environment = "production"
|
63
|
+
end
|
64
|
+
|
65
|
+
File.open(options[:fs_log]) do |log|
|
66
|
+
log.extend(File::Tail)
|
67
|
+
log.interval = 10
|
68
|
+
log.backward 0
|
69
|
+
log.tail {|line|
|
70
|
+
begin
|
71
|
+
event = SentryFS.parse(line)
|
72
|
+
SentryFS.capture(event) if event
|
73
|
+
rescue => e
|
74
|
+
logger.error line
|
75
|
+
logger.error e.message
|
76
|
+
logger.error e.backtrace
|
77
|
+
end
|
78
|
+
}
|
79
|
+
end
|
data/lib/sentry_fs.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module SentryFS
|
4
|
+
class Event
|
5
|
+
attr_reader :uuid
|
6
|
+
attr_reader :message
|
7
|
+
attr_reader :extra
|
8
|
+
attr_reader :full_message
|
9
|
+
attr_reader :level
|
10
|
+
|
11
|
+
def initialize(uuid:, message:, extra: {}, full_message: nil, level: "err")
|
12
|
+
@uuid = uuid
|
13
|
+
@message = message
|
14
|
+
@extra = extra
|
15
|
+
@full_message = full_message
|
16
|
+
@level = level
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
EXPRESSIONS = {
|
21
|
+
global: /\A\S+ \S+ \[(?<level>WARNING|ALERT|CRIT|ERR)\] (?<line>\S+) (?<message>.*)\z/,
|
22
|
+
session: /\A(?<uuid>\S+) \S+ \S+ \[(?<level>WARNING|ALERT|CRIT|ERR)\] (?<line>\S+) (?<message>.*)\z/,
|
23
|
+
odbc: /\A(?<message>.*CODE.*ERROR.*)\z/
|
24
|
+
}
|
25
|
+
|
26
|
+
def self.parse(log_line)
|
27
|
+
log_line.chomp!
|
28
|
+
EXPRESSIONS.each {|name, regexp|
|
29
|
+
match = log_line.match(regexp)
|
30
|
+
if match
|
31
|
+
uuid = match.names.include?("uuid") ? match[:uuid] : nil
|
32
|
+
line = match.names.include?("line") ? match[:line] : nil
|
33
|
+
level = match.names.include?("level") ? match[:level].downcase : "err"
|
34
|
+
begin
|
35
|
+
json = JSON.parse(match[:message])
|
36
|
+
message = json["message"]
|
37
|
+
extra = json["extra"]
|
38
|
+
rescue JSON::ParserError
|
39
|
+
message = [line, match[:message]].compact.join(" ")
|
40
|
+
extra = {}
|
41
|
+
end
|
42
|
+
event = Event.new(
|
43
|
+
uuid: uuid,
|
44
|
+
message: message,
|
45
|
+
full_message: log_line,
|
46
|
+
extra: extra,
|
47
|
+
level: level
|
48
|
+
)
|
49
|
+
return event
|
50
|
+
end
|
51
|
+
}
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.capture(event)
|
56
|
+
Raven.capture_message(event.message, {
|
57
|
+
level: event.level,
|
58
|
+
extra: {
|
59
|
+
uuid: event.uuid,
|
60
|
+
full_message: event.full_message
|
61
|
+
}.merge(event.extra)
|
62
|
+
})
|
63
|
+
end
|
64
|
+
end
|
data/sentry_fs.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "sentry_fs"
|
3
|
+
s.version = "0.6"
|
4
|
+
s.date = "2015-10-21"
|
5
|
+
s.summary = "Parse FreeSWITCH logs and report errors to Sentry"
|
6
|
+
s.email = "hv@firmafon.dk"
|
7
|
+
s.homepage = "http://github.com/firmafon/sentry_fs"
|
8
|
+
s.description = "Parse FreeSWITCH logs and report errors to Sentry"
|
9
|
+
s.authors = ["Harry Vangberg"]
|
10
|
+
s.executables = ["sentry_fs"]
|
11
|
+
s.files = [
|
12
|
+
"sentry_fs.gemspec",
|
13
|
+
"lib/sentry_fs.rb",
|
14
|
+
"bin/sentry_fs"
|
15
|
+
]
|
16
|
+
s.test_files = [
|
17
|
+
"test/test_helper.rb",
|
18
|
+
"test/unit/test_sentry_fs.rb"
|
19
|
+
]
|
20
|
+
s.add_dependency "file-tail", "~> 1.0"
|
21
|
+
s.add_dependency "sentry-raven", "~> 0.14.0"
|
22
|
+
s.add_dependency "json"
|
23
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class TestSentryFS < MiniTest::Unit::TestCase
|
4
|
+
LOG_LEVELS = %w(WARNING ALERT CRIT ERR)
|
5
|
+
|
6
|
+
LOG_LEVELS.each do |level|
|
7
|
+
define_method(:"test_parse_global_#{level}") do
|
8
|
+
log = "2013-03-19 10:41:53.556663 [#{level}] mod_db.c:117 Error Opening DB\n"
|
9
|
+
event = SentryFS.parse(log)
|
10
|
+
|
11
|
+
assert_nil event.uuid
|
12
|
+
assert_equal "mod_db.c:117 Error Opening DB", event.message
|
13
|
+
assert_equal log, event.full_message
|
14
|
+
assert_equal level.downcase, event.level
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
LOG_LEVELS.each do |level|
|
19
|
+
define_method(:"test_parse_session_#{level}") do
|
20
|
+
log = "447d3058-90be-11e2-906b-d954932e9cdf 2013-03-19 10:56:04.307690 [#{level}] mod_sofia.c:4224 Invalid Gateway\n"
|
21
|
+
event = SentryFS.parse(log)
|
22
|
+
|
23
|
+
assert_equal "447d3058-90be-11e2-906b-d954932e9cdf", event.uuid
|
24
|
+
assert_equal "mod_sofia.c:4224 Invalid Gateway", event.message
|
25
|
+
assert_equal log, event.full_message
|
26
|
+
assert_equal level.downcase, event.level
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_parse_global_json_error
|
31
|
+
log = '2013-03-19 10:41:53.556663 [ERR] utils.js:123 {"message":"error 123", "extra": {"some_var":"some_data"}}' + "\n"
|
32
|
+
event = SentryFS.parse(log)
|
33
|
+
|
34
|
+
assert_nil event.uuid
|
35
|
+
assert_equal "error 123", event.message
|
36
|
+
assert_equal log, event.full_message
|
37
|
+
assert_equal({"some_var" => "some_data"}, event.extra)
|
38
|
+
assert_equal "err", event.level
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_parse_session_json_error
|
42
|
+
log = '447d3058-90be-11e2-906b-d954932e9cdf 2013-03-19 10:56:04.307690 [ERR] utils.js:123 {"message":"error 123", "extra":{"some_var":"some_data"}}' + "\n"
|
43
|
+
event = SentryFS.parse(log)
|
44
|
+
|
45
|
+
assert_equal "447d3058-90be-11e2-906b-d954932e9cdf", event.uuid
|
46
|
+
assert_equal "error 123", event.message
|
47
|
+
assert_equal log, event.full_message
|
48
|
+
assert_equal({"some_var" => "some_data"}, event.extra)
|
49
|
+
assert_equal "err", event.level
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_parse_odbc_error_without_timestamp
|
53
|
+
log = "[STATE: 42S22 CODE 1054 ERROR: [unixODBC][MySQL][ODBC 3.51 Driver][mysqld-5.1.39-ndb-7.0.9-1ubuntu7]Unknown column 'undefined' in 'where clause'\n"
|
54
|
+
|
55
|
+
event = SentryFS.parse(log)
|
56
|
+
|
57
|
+
assert_nil event.uuid
|
58
|
+
assert_equal log, event.message
|
59
|
+
assert_equal log, event.full_message
|
60
|
+
assert_equal "err", event.level
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_parse_odbc_error_with_timestamp
|
64
|
+
log = "2013-04-24 07:28:09.347700 [ERR] switch_core_sqldb.c:476 SQL ERR [STATE: HY000 CODE 1205 ERROR: [unixODBC][MySQL][ODBC 3.51 Driver][mysqld-5.1.39-ndb-7.0.9-1ubuntu7]Lock wait timeout exceeded; try restarting transaction\n"
|
65
|
+
|
66
|
+
event = SentryFS.parse(log)
|
67
|
+
|
68
|
+
message = "switch_core_sqldb.c:476 SQL ERR [STATE: HY000 CODE 1205 ERROR: [unixODBC][MySQL][ODBC 3.51 Driver][mysqld-5.1.39-ndb-7.0.9-1ubuntu7]Lock wait timeout exceeded; try restarting transaction"
|
69
|
+
|
70
|
+
assert_nil event.uuid
|
71
|
+
assert_equal message, event.message
|
72
|
+
assert_equal log, event.full_message
|
73
|
+
assert_equal "err", event.level
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_parse_something_else
|
77
|
+
log = "0ea0aa02-acd2-11e2-87e3-2f16ea487161 EXECUTE sofia/external/22334455@192.168.90.1 javascript(voicemail.js 4571992020)\n"
|
78
|
+
|
79
|
+
event = SentryFS.parse(log)
|
80
|
+
|
81
|
+
assert_nil event
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sentry_fs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.6'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Harry Vangberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: file-tail
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sentry-raven
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.14.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.14.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Parse FreeSWITCH logs and report errors to Sentry
|
56
|
+
email: hv@firmafon.dk
|
57
|
+
executables:
|
58
|
+
- sentry_fs
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/sentry_fs
|
63
|
+
- lib/sentry_fs.rb
|
64
|
+
- sentry_fs.gemspec
|
65
|
+
- test/test_helper.rb
|
66
|
+
- test/unit/test_sentry_fs.rb
|
67
|
+
homepage: http://github.com/firmafon/sentry_fs
|
68
|
+
licenses: []
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.4.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Parse FreeSWITCH logs and report errors to Sentry
|
90
|
+
test_files:
|
91
|
+
- test/test_helper.rb
|
92
|
+
- test/unit/test_sentry_fs.rb
|
93
|
+
has_rdoc:
|