reevoo_app_monitor 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0d4488b68e07d2fb7d83150a4da60b0709fdd9b6
4
+ data.tar.gz: 39ef1f29fdcf9302e3c8de1424521cee0a034286
5
+ SHA512:
6
+ metadata.gz: 54a3659a2b607cbdb2ff9611356c4e0f0d3a8924a4ec622e9f2552ac70db64a49116af08a94d4591910c7a5e93a24771431e1f9eadf97540152f7c6ff9cc7a4f
7
+ data.tar.gz: e5c3931d595f0f0299c6809a6697215f2cf8e70d300cc367ad1cab61a1f80d7b8054e6f626c566a6fb4e6e4a93c000991c296af94350993edfda5c81ab316497
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ /Gemfile.lock
2
+ /coverage/
3
+ /spec/reports/
4
+ /tmp/
5
+ .idea
6
+ log/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.4
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at alex.malkov@reevoo.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in reevoo_app_monitor.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'pry-nav'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Reevoo Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # ReevooAppMonitor
2
+
3
+ ReevooAppMonitor consolidates logstasher, statsd and sentry raven into a single library with one setup.
4
+ It's designed for Rack/Grape apps. It automatically tracks all log messages into logstash, exceptions into
5
+ sentry and updates exceptions stats in statsd. It also allow you to call methods directly on instances of statsd
6
+ and raven if needed.
7
+
8
+ ## Installation
9
+
10
+ ### In your Gemfile:
11
+
12
+ ```ruby
13
+ gem 'reevoo_app_monitor'
14
+ ```
15
+
16
+ ### Init app monitor:
17
+
18
+ ```ruby
19
+ module TestApp
20
+ def self.production?
21
+ ENV["RACK_ENV"] == "production"
22
+ end
23
+
24
+ def self.app_monitor
25
+ @app_monitor ||= ReevooAppMonitor.new(
26
+ app_name: "foo_app",
27
+ root_dir: Rack::Directory.new("").root
28
+ device: STDOUT,
29
+ raven_conf: {
30
+ dsn: "https://00c73aa8f93f4hbwjehb4r20af10afb@app.getsentry.com/502146"
31
+ }
32
+ ) if production?
33
+ end
34
+
35
+ def self.logger
36
+ production? ? app_monitor.logger : Logger.new(STDOUT)
37
+ end
38
+
39
+ def self.stats
40
+ production? ? app_monitor.stats : ReevooAppMonitor.nil_service
41
+ end
42
+ end
43
+ ```
44
+
45
+ All constructor arguments:
46
+
47
+ ```ruby
48
+ ReevooAppMonitor.new(
49
+ app_name: "foo_app",
50
+ root_dir: Rack::Directory.new("").root
51
+ device: STDOUT, # default is file log in log/logstasher.log
52
+ integrations: [:logstasher, :statsd, :raven], # you can turn off individual integrations
53
+ raven_conf: {
54
+ dsn: "https://00c73aa8f93f4hbwjehb4r20af10afb@app.getsentry.com/502146"
55
+ },
56
+ statsd_conf: { # in most cases you should be fine with default localhost:8125
57
+ host: "my-host",
58
+ port: 1234
59
+ }
60
+ )
61
+ ```
62
+
63
+
64
+ ### Setup Grape request/exception logging
65
+
66
+ Add to Gemfile
67
+
68
+ ```ruby
69
+ gem 'grape_logging'
70
+ ```
71
+
72
+ Setup in Grape::API class
73
+
74
+ ```ruby
75
+ module TestApp
76
+ class API < Grape::API
77
+ logger TestApp.logger
78
+ use GrapeLogging::Middleware::RequestLogger, logger: TestApp.logger
79
+
80
+ rescue_from TestApp::NotFound do |err|
81
+ # Tag your exception
82
+ API.logger.info(exception: err, tags: "rescued_exception", status: 404)
83
+ error_response(message: "Not found", status: 404)
84
+ end
85
+
86
+ rescue_from :all do |e|
87
+ API.logger.error(e)
88
+ error_response(message: e.message, status: 500)
89
+ end
90
+ end
91
+ end
92
+ ```
93
+
94
+
95
+ ### Track statsd metrics directly
96
+
97
+ You can call all methods supported by https://github.com/DataDog/dogstatsd-ruby
98
+
99
+ ```ruby
100
+ TestApp.stats.increment('foo.bar')
101
+ TestApp.stats.gauge('foo.online', 123)
102
+ TestApp.stats.histogram('foo.upload.size', 1234)
103
+ TestApp.stats.time('page.render') do
104
+ render_page('home.html')
105
+ end
106
+ ```
107
+
108
+
109
+ ## License
110
+
111
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "reevoo_app_monitor"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,63 @@
1
+ require "reevoo_app_monitor/version"
2
+ require "reevoo_app_monitor/logger"
3
+ require "logstasher"
4
+ require "statsd"
5
+ require "raven/base"
6
+
7
+ class ReevooAppMonitor
8
+ DEFAULT_INTEGRATIONS = [:logstasher, :statsd, :raven]
9
+
10
+ attr_reader :logger, :stats
11
+
12
+ def initialize(app_name:, root_dir: nil, device: nil, level: ::Logger::INFO,
13
+ env: ENV["RACK_ENV"], integrations: DEFAULT_INTEGRATIONS, statsd_conf: {}, raven_conf: {})
14
+
15
+ @stats = init_statsd(statsd_conf, app_name, env) if integrations.include?(:statsd)
16
+ raven = init_raven(raven_conf, app_name, env) if integrations.include?(:raven)
17
+ formatter = LogStasher::LogFormatter.new(app_name, root_dir) if integrations.include?(:logstasher)
18
+
19
+ device ||= get_device(root_dir)
20
+ @logger = init_logger(device, level, formatter, statsd: @stats, raven: raven)
21
+ end
22
+
23
+ def nil_service
24
+ @nil_service ||= ReevooAppMonitor::NilService.new
25
+ end
26
+
27
+ private
28
+
29
+ def get_device(root_dir)
30
+ return STDOUT unless root_dir
31
+
32
+ log_dir = File.join(root_dir, 'log')
33
+ Dir.mkdir(log_dir) unless File.exists?(log_dir)
34
+ device = File.join(log_dir, 'logstasher.log')
35
+ FileUtils.touch(device)
36
+ device
37
+ end
38
+
39
+ def init_logger(device, level, formatter, statsd: nil, raven: nil)
40
+ Logger.new(device, statsd: statsd, raven: raven).tap do |new_logger|
41
+ new_logger.level = level
42
+ new_logger.formatter = formatter if formatter
43
+ end
44
+ end
45
+
46
+ def init_statsd(statsd_conf, app_name, env)
47
+ Statsd.new(
48
+ statsd_conf.fetch(:host, 'localhost'),
49
+ statsd_conf.fetch(:port, 8125),
50
+ namespace: app_name,
51
+ tags: ["env:#{env}"],
52
+ )
53
+ end
54
+
55
+ def init_raven(raven_conf, app_name, env)
56
+ Raven.configure do |config|
57
+ config.tags = { env: env }
58
+ config.silence_ready = true
59
+ raven_conf.each_pair { |key, value| config.send("#{key}=", value) }
60
+ end
61
+ Raven
62
+ end
63
+ end
@@ -0,0 +1,60 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'logger'
3
+
4
+ class ReevooAppMonitor
5
+ class Logger < ::Logger
6
+
7
+ def initialize(device, statsd: nil, raven: nil)
8
+ super(device)
9
+ @statsd = statsd
10
+ @raven = raven
11
+ end
12
+
13
+ def add(severity, message = nil, progname = nil, &block)
14
+ super
15
+
16
+ # Naming of these arguments is weird, if no block is given to debug|info|warn|error|fatal method
17
+ # it passes the message to #add as a progname and message argument is always nil. See the test for this class.
18
+ exception = extract_exception(progname)
19
+ tags = extract_tags(progname)
20
+ track_exception_to_statsd(severity, exception, tags) if exception && @statsd
21
+ track_exception_to_raven(severity, exception, tags) if exception && @raven
22
+ end
23
+
24
+ private
25
+
26
+ def extract_exception(message)
27
+ if message.is_a?(Exception)
28
+ message
29
+ elsif message.is_a?(Hash) && message[:exception] && message[:exception].is_a?(Exception)
30
+ message[:exception]
31
+ end
32
+ end
33
+
34
+ def extract_tags(message)
35
+ message.is_a?(Hash) ? Array(message[:tags]) : []
36
+ end
37
+
38
+ def track_exception_to_statsd(severity, exception, tags)
39
+ key_parts = ['exception', exception.class.to_s.underscore]
40
+ if exception.message != exception.class.to_s # message is the class name if not provided when raising
41
+ # Remove all non LATIN1 characters and get only first 100 characters
42
+ key_parts << exception.message.downcase.gsub(/[^a-zA-Z0-9]/, '_')[0...100]
43
+ end
44
+
45
+ @statsd.increment(key_parts.join('.'), tags: ["severity:#{severity_text(severity)}"] + tags)
46
+ end
47
+
48
+ def track_exception_to_raven(severity, exception, tags)
49
+ return if severity < ERROR
50
+ options = { tags: { severity: severity_text(severity) } }
51
+ options[:extra] = { extra_tags: tags } unless tags.empty?
52
+ @raven.capture_exception(exception, options)
53
+ end
54
+
55
+ def severity_text(severity)
56
+ format_severity(severity).downcase
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ class ReevooAppMonitor
2
+ class NilService
3
+ def method_missing(*args)
4
+ nil
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ require "logstasher/rack/common_logger_adapter"
2
+
3
+ class ReevooAppMonitor
4
+ module Rack
5
+ class CommonLoggerAdapter < LogStasher::Rack::CommonLoggerAdapter
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ class ReevooAppMonitor
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'reevoo_app_monitor/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "reevoo_app_monitor"
8
+ spec.version = ReevooAppMonitor::VERSION
9
+ spec.authors = ["Alex Malkov", "David Sevcik"]
10
+ spec.email = ["alex.malkov@reevoo.com", "david.sevcik@reevoo.com"]
11
+
12
+ spec.summary = %q{Produces log in the logstash format with ability to log events into DataDog}
13
+ spec.description = %q{Produces log in the logstash format with ability to log events into DataDog}
14
+ spec.homepage = "https://github.com/reevoo/reevoo_app_monitor"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "rv-logstasher", "~> 1.3"
23
+ spec.add_dependency "dogstatsd-ruby", "~> 1.6"
24
+ spec.add_dependency "sentry-raven", "~> 0.15.6"
25
+ spec.add_dependency "activesupport"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.11"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reevoo_app_monitor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Alex Malkov
8
+ - David Sevcik
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2016-04-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rv-logstasher
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: dogstatsd-ruby
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.6'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.6'
42
+ - !ruby/object:Gem::Dependency
43
+ name: sentry-raven
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 0.15.6
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 0.15.6
56
+ - !ruby/object:Gem::Dependency
57
+ name: activesupport
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.11'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.11'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '10.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '10.0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.0'
112
+ description: Produces log in the logstash format with ability to log events into DataDog
113
+ email:
114
+ - alex.malkov@reevoo.com
115
+ - david.sevcik@reevoo.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - ".travis.yml"
123
+ - CODE_OF_CONDUCT.md
124
+ - Gemfile
125
+ - LICENSE.txt
126
+ - README.md
127
+ - Rakefile
128
+ - bin/console
129
+ - bin/setup
130
+ - lib/reevoo_app_monitor.rb
131
+ - lib/reevoo_app_monitor/logger.rb
132
+ - lib/reevoo_app_monitor/nil_service.rb
133
+ - lib/reevoo_app_monitor/rack/common_logger_adapter.rb
134
+ - lib/reevoo_app_monitor/version.rb
135
+ - reevoo_app_monitor.gemspec
136
+ homepage: https://github.com/reevoo/reevoo_app_monitor
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.4.5.1
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: Produces log in the logstash format with ability to log events into DataDog
160
+ test_files: []