fluent-plugin-sentry 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ vendor/*
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.1.0
5
+ - 2.0.0
6
+ - 1.9.3
7
+
8
+ before_script:
9
+ - export RAILS_ENV=default
10
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-sentry.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2014- Kentaro Yoshida
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
14
+
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # fluent-plugin-sentry [![Build Status](https://travis-ci.org/y-ken/fluent-plugin-sentry.png?branch=master)](https://travis-ci.org/y-ken/fluent-plugin-sentry)
2
+
3
+ ## Overview
4
+
5
+ Fluentd output plugin to send aggregated errors/exception events to Sentry which are a realtime event logging and aggregation platform.<br>
6
+
7
+ If you have sent events to Sentry directory from front webpage without aggregation, you may got down response time and performance problem (e.g. PHP).<br>
8
+ To use Sentry and Fluentd together, it will got best perfomance because Fluentd acts messege queue for Sentry.
9
+
10
+ * [Sentry Official web](https://getsentry.com/welcome/)
11
+ * [Sentry Documents](http://sentry.readthedocs.org/en/latest/) [Screenshots](https://github.com/getsentry/sentry#screenshots)
12
+
13
+ ## Installation
14
+
15
+ install with gem or fluent-gem command as:
16
+
17
+ `````
18
+ ### native gem
19
+ gem install fluent-plugin-sentry
20
+
21
+ ### td-agent gem
22
+ /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-sentry
23
+ `````
24
+
25
+ ## Preparation
26
+
27
+ create sentry dashboard first. It could start with cost free!!
28
+
29
+ * Create an account at https://getsentry.com/pricing/
30
+
31
+ OR
32
+
33
+ * Launch Sentry at the self manager server with https://github.com/getsentry/sentry
34
+
35
+ ## Usage
36
+
37
+ ```xml
38
+ <source>
39
+ type forward
40
+ </source>
41
+
42
+ <match notify.**>
43
+ type sentry
44
+
45
+ # Set endpoint API URL
46
+ endpoint_url https://${api_key}:${api_password}@app.getsentry.com/${project_id}
47
+
48
+ # Set default events value of 'server_name'
49
+ hostname_command hostname -s
50
+
51
+ # rewrite shown tag name for Sentry dashboard
52
+ remove_tag_prefix notify.
53
+ </match>
54
+ ```
55
+
56
+ ## Parameters
57
+
58
+ * endpoint_url (Required)<br>
59
+ Set endpoint API URL which shows at Sentry dashboard. (it is not sentry account information)
60
+
61
+ * default_level<br>
62
+ [default] error
63
+
64
+ * defalut_logger<br>
65
+ [default] flunetd
66
+
67
+ * hostname_command<br>
68
+ Set default frontend value of 'server_name'
69
+
70
+ * flush_interval<br>
71
+ [default] 0sec
72
+
73
+ It also support rewriting Tag with SetTagKeyMixin.
74
+
75
+ * remove_tag_prefix
76
+ * remove_tag_suffix
77
+ * add_tag_prefix
78
+ * add_tag_suffix
79
+
80
+ ## Blog Articles
81
+
82
+ ## TODO
83
+
84
+ Pull requests are very welcome!!
85
+
86
+ ## Copyright
87
+
88
+ Copyright © 2014- Kentaro Yoshida ([@yoshi_ken](https://twitter.com/yoshi_ken))
89
+
90
+ ## License
91
+
92
+ Apache License, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ Rake::TestTask.new(:test) do |test|
4
+ test.libs << 'lib' << 'test'
5
+ test.pattern = 'test/**/test_*.rb'
6
+ test.verbose = true
7
+ end
8
+
9
+ task :default => :test
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-sentry"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Kentaro Yoshida"]
9
+ spec.email = ["y.ken.studio@gmail.com"]
10
+ spec.summary = %q{Fluentd output plugin to send aggregated errors/exception events to sentry which are a realtime event logging and aggregation platform.}
11
+ spec.homepage = "https://github.com/y-ken/fluent-plugin-sentry"
12
+ spec.license = "Apache License, Version 2.0"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler"
20
+ spec.add_development_dependency "rake"
21
+ spec.add_development_dependency "webmock"
22
+ spec.add_runtime_dependency "fluentd"
23
+ spec.add_runtime_dependency "sentry-raven"
24
+ end
@@ -0,0 +1,81 @@
1
+ class Fluent::SentryOutput < Fluent::BufferedOutput
2
+ Fluent::Plugin.register_output('sentry', self)
3
+
4
+ include Fluent::HandleTagNameMixin
5
+
6
+ LOG_LEVEL = %w(fatal error warning info debug)
7
+ EVENT_KEYS = %w(logger level tags modules message)
8
+ DEFAULT_HOSTNAME_COMMAND = 'hostname'
9
+
10
+ config_param :default_level, :string, :default => 'error'
11
+ config_param :default_logger, :string, :default => 'fluentd'
12
+ config_param :endpoint_url, :string
13
+ config_param :flush_interval, :time, :default => 0
14
+ config_param :hostname_command, :string, :default => 'hostname'
15
+
16
+ def initialize
17
+ require 'time'
18
+ require 'raven'
19
+
20
+ super
21
+ end
22
+
23
+ def configure(conf)
24
+ super
25
+
26
+ if @endpoint_url.nil?
27
+ raise Fluent::ConfigError, "sentry: missing parameter for 'endpoint_url'"
28
+ end
29
+
30
+ unless LOG_LEVEL.include?(@default_level)
31
+ raise Fluent::ConfigError, "sentry: unsupported default reporting log level for 'default_level'"
32
+ end
33
+
34
+ hostname_command = @hostname_command || DEFAULT_HOSTNAME_COMMAND
35
+ hostname = `#{hostname_command}`.chomp
36
+
37
+ @configuration = Raven::Configuration.new
38
+ @configuration.server = @endpoint_url
39
+ @configuration.server_name = hostname
40
+ @client = Raven::Client.new(@configuration)
41
+ end
42
+
43
+ def start
44
+ super
45
+ end
46
+
47
+ def format(tag, time, record)
48
+ [tag, time, record].to_msgpack
49
+ end
50
+
51
+ def shutdown
52
+ super
53
+ end
54
+
55
+ def write(chunk)
56
+ chunk.msgpack_each do |tag, time, record|
57
+ begin
58
+ notify_sentry(tag, time, record)
59
+ rescue => e
60
+ $log.error("Sentry Error:", :error_class => e.class, :error => e.message)
61
+ end
62
+ end
63
+ end
64
+
65
+ def notify_sentry(tag, time, record)
66
+ event = Raven::Event.new(
67
+ :configuration => @configuration,
68
+ :context => Raven::Context.new,
69
+ :message => record['message']
70
+ )
71
+ event.timestamp = Time.at(time).utc.strftime('%Y-%m-%dT%H:%M:%S')
72
+ event.logger = record['logger'] || @default_logger
73
+ event.level = record['level'] || @default_level
74
+ event.tags = record['tags'] || { :tag => tag }
75
+ event.extra = record.reject{ |key| EVENT_KEYS.include?(key) }
76
+ event.modules = record['modules'] || nil
77
+ event.platform = record['platform'] if record['platform']
78
+ event.server_name = record['server_name'] if record['server_name']
79
+ @client.send(event)
80
+ end
81
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/out_sentry'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+ require 'webmock/test_unit'
3
+ require 'yajl'
4
+
5
+ WebMock.disable_net_connect!
6
+
7
+ class SentryOutputTest < Test::Unit::TestCase
8
+ def setup
9
+ Fluent::Test.setup
10
+ end
11
+
12
+ CONFIG = %[
13
+ type sentry
14
+ endpoint_url https://user:password@app.getsentry.com/12345
15
+ hostname_command hostname -s
16
+ remove_tag_prefix input.
17
+ ]
18
+
19
+ def create_driver(conf=CONFIG,tag='test')
20
+ Fluent::Test::OutputTestDriver.new(Fluent::SentryOutput, tag).configure(conf)
21
+ end
22
+
23
+ def stub_endpoint(url="https://app.getsentry.com/api/12345/store/")
24
+ parser = Yajl::Parser.new
25
+ stub_request(:post, url).with do |req|
26
+ @content_type = req.headers["Content-Type"]
27
+ @body = parser.parse(req.body)
28
+ end
29
+ end
30
+
31
+ def test_configure
32
+ assert_raise(Fluent::ConfigError) {
33
+ d = create_driver('')
34
+ }
35
+ d = create_driver(CONFIG)
36
+ assert_equal 'https://user:password@app.getsentry.com/12345', d.instance.config['endpoint_url']
37
+ end
38
+
39
+ def test_emit
40
+ stub_endpoint
41
+ d1 = create_driver(CONFIG, 'input.app1_error')
42
+ emit_level = 'warning'
43
+ emit_message = 'error has occoured.'
44
+ emit_extra = {'foo' => {'array' => [1,2,3]}, 'hash' => {'nest' => 'data'}}
45
+ d1.run do
46
+ d1.emit({
47
+ 'level' => emit_level,
48
+ 'message' => emit_message,
49
+ 'something' => emit_extra
50
+ })
51
+ end
52
+ p @body
53
+ emits = d1.emits
54
+ assert_equal 0, emits.length
55
+ assert_equal 'application/json', @content_type
56
+ assert_equal emit_message, @body['message']
57
+ timestamp = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S')
58
+ assert_equal timestamp, @body['timestamp']
59
+ assert_equal emit_level, @body['level']
60
+ assert_equal '12345', @body['project']
61
+ assert_equal 'fluentd', @body['logger']
62
+ assert_equal 'ruby', @body['platform']
63
+ assert_equal 'app1_error', @body['tags'][':tag']
64
+ hostname = `#{d1.instance.config['hostname_command']}`.chomp
65
+ assert_equal hostname, @body['server_name']
66
+ extra_message = {'something' => emit_extra}
67
+ assert_equal extra_message, @body['extra']
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-sentry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kentaro Yoshida
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: webmock
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: fluentd
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sentry-raven
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description:
95
+ email:
96
+ - y.ken.studio@gmail.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - .travis.yml
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - fluent-plugin-sentry.gemspec
108
+ - lib/fluent/plugin/out_sentry.rb
109
+ - test/helper.rb
110
+ - test/plugin/test_out_sentry.rb
111
+ homepage: https://github.com/y-ken/fluent-plugin-sentry
112
+ licenses:
113
+ - Apache License, Version 2.0
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 1.8.23
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Fluentd output plugin to send aggregated errors/exception events to sentry
136
+ which are a realtime event logging and aggregation platform.
137
+ test_files:
138
+ - test/helper.rb
139
+ - test/plugin/test_out_sentry.rb