yarder 0.0.1 → 0.0.2

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: c5946b3b2b8f0f66e24c29b4f368815de55e5824
4
+ data.tar.gz: 97f4b3b4ca339f3f8784fdf915b744102f1d0eb7
5
+ SHA512:
6
+ metadata.gz: 8fc443ac309df22ba604677f4f3e6665b9ed6aabce70859e66b98c6b61b0b995a8cad72c4952c53e3bb4400874d0661979bc2cc8517109687b5ea52067256dbd
7
+ data.tar.gz: 48f42076840462615c8ac7c07bc48b3b676e0594e0d400e3d2e1b789fce49997f67651915ab202e9eb194df44a904a8c752ffc5b55b6429daf43b7e24da21c44
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2012 YOURNAME
1
+ Copyright 2012 Jeffrey Jones
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Yarder
2
2
 
3
3
  [![Build Status](https://secure.travis-ci.org/rurounijones/yarder.png)](http://travis-ci.org/rurounijones/yarder)
4
+ [![Coverage Status](https://coveralls.io/repos/rurounijones/yarder/badge.png?branch=master)](https://coveralls.io/r/rurounijones/yarder)
5
+ [![Code Climate](https://codeclimate.com/github/rurounijones/yarder.png)](https://codeclimate.com/github/rurounijones/yarder)
4
6
  [![Dependency Status](https://gemnasium.com/rurounijones/yarder.png)](https://gemnasium.com/rurounijones/yarder)
5
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rurounijones/yarder)
6
7
 
7
8
  JSON Based Replacement logging system for Ruby on Rails.
8
9
 
@@ -82,6 +83,18 @@ serialized Logstash::Event entries there is no need to setup any filters
82
83
 
83
84
  ### Known issues
84
85
 
85
- Yarder currently creates nested JSON. While this is supported in Logstash and Elastic Search the web
86
- interfaces do not as yet support it. Depending on whether support is possible or not Yarder may
87
- change to a non-nested format.
86
+ Yarder currently creates nested JSON. Kibana has pretty good (With a few small UI problems) support
87
+ for nested JSON but logstash web does not.
88
+
89
+ ## Developers
90
+
91
+ Thoughts, suggestions, opinions and contributions are welcome.
92
+
93
+ When contributing please make sure to run your tests with warnings enabled and make sure that
94
+ yarder creates no warnings. (Warnings from other libraries like capybara etc. are ok)
95
+
96
+ ```
97
+ RUBYOPT=-w rake
98
+ ```
99
+
100
+
data/lib/yarder.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'yarder/railtie' if defined?(Rails)
2
2
  require 'yarder/rack/logger'
3
+ require 'yarder/event'
3
4
  require 'logstash-event'
4
5
  require 'yarder/logger'
5
6
  require 'yarder/tagged_logging'
@@ -19,7 +19,8 @@ module Yarder
19
19
  def process_action(event)
20
20
 
21
21
  payload = event.payload
22
- additions = ::ActionController::Base.log_process_action(payload)
22
+ #TODO Think about additions. Comment out for the moment to shut up warnings
23
+ #additions = ::ActionController::Base.log_process_action(payload)
23
24
 
24
25
  params = payload[:params].except(*INTERNAL_PARAMS)
25
26
  entry.fields['parameters'] = params unless params.empty?
@@ -1,3 +1,5 @@
1
+ require "securerandom"
2
+
1
3
  module Yarder
2
4
  module ActiveRecord
3
5
  class LogSubscriber < ::ActiveSupport::LogSubscriber
@@ -27,7 +29,6 @@ module Yarder
27
29
 
28
30
  return if 'SCHEMA' == payload[:name]
29
31
 
30
- entry.fields['sql'] ||= []
31
32
  sql_entry = {}
32
33
  sql_entry['name'] = payload[:name]
33
34
  sql_entry['duration'] = event.duration
@@ -43,7 +44,7 @@ module Yarder
43
44
 
44
45
  sql_entry['binds'] = binds unless binds.nil?
45
46
 
46
- entry.fields['sql'] << sql_entry
47
+ write_entry sql_entry
47
48
  end
48
49
 
49
50
  def identity(event)
@@ -56,18 +57,30 @@ module Yarder
56
57
  sql_entry['line'] = payload[:line]
57
58
  sql_entry['duration'] = payload[:duration]
58
59
 
59
- entry.fields['sql'] << sql_entry
60
+ write_entry sql_entry
60
61
  end
61
62
 
62
63
  private
63
64
 
65
+ def write_entry(sql_entry)
66
+ entry = log_entry
67
+ entry.fields['sql'] ||= []
68
+ entry.fields['sql'] << sql_entry
69
+ entry.write(false)
70
+ end
71
+
64
72
  def logger
65
73
  ::ActiveRecord::Base.logger
66
74
  end
67
75
 
68
-
69
- def entry
70
- Yarder.log_entries[Thread.current]
76
+ def log_entry
77
+ Yarder.log_entries[Thread.current] ||
78
+ Yarder::Event.new(Rails.logger, false).tap do |entry|
79
+ entry.fields['uuid'] = SecureRandom.uuid
80
+ #TODO Should really move this into the base logger
81
+ entry.source = Socket.gethostname
82
+ entry.type = "rails_json_log"
83
+ end
71
84
  end
72
85
 
73
86
  end
@@ -1,105 +1,110 @@
1
1
  # encoding: utf-8
2
2
 
3
- class Object
4
- # An object is blank if it's false, empty, or a whitespace string.
5
- # For example, '', ' ', +nil+, [], and {} are all blank.
6
- #
7
- # This simplifies:
8
- #
9
- # if address.nil? || address.empty?
10
- #
11
- # ...to:
12
- #
13
- # if address.blank?
14
- def blank?
15
- respond_to?(:empty?) ? empty? : !self
16
- end
3
+ # This file is copied verbatim from ActiveSupport for compatibility
4
+ # should yarder be used outside of a Rails project. Therefor we
5
+ # won't process this file if ActiveSupport is already defined
6
+ unless defined?(ActiveSupport)
7
+ class Object
8
+ # An object is blank if it's false, empty, or a whitespace string.
9
+ # For example, '', ' ', +nil+, [], and {} are all blank.
10
+ #
11
+ # This simplifies:
12
+ #
13
+ # if address.nil? || address.empty?
14
+ #
15
+ # ...to:
16
+ #
17
+ # if address.blank?
18
+ def blank?
19
+ respond_to?(:empty?) ? empty? : !self
20
+ end
17
21
 
18
- # An object is present if it's not <tt>blank?</tt>.
19
- def present?
20
- !blank?
21
- end
22
+ # An object is present if it's not <tt>blank?</tt>.
23
+ def present?
24
+ !blank?
25
+ end
22
26
 
23
- # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
24
- # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
25
- #
26
- # This is handy for any representation of objects where blank is the same
27
- # as not present at all. For example, this simplifies a common check for
28
- # HTTP POST/query parameters:
29
- #
30
- # state = params[:state] if params[:state].present?
31
- # country = params[:country] if params[:country].present?
32
- # region = state || country || 'US'
33
- #
34
- # ...becomes:
35
- #
36
- # region = params[:state].presence || params[:country].presence || 'US'
37
- def presence
38
- self if present?
27
+ # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
28
+ # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
29
+ #
30
+ # This is handy for any representation of objects where blank is the same
31
+ # as not present at all. For example, this simplifies a common check for
32
+ # HTTP POST/query parameters:
33
+ #
34
+ # state = params[:state] if params[:state].present?
35
+ # country = params[:country] if params[:country].present?
36
+ # region = state || country || 'US'
37
+ #
38
+ # ...becomes:
39
+ #
40
+ # region = params[:state].presence || params[:country].presence || 'US'
41
+ def presence
42
+ self if present?
43
+ end
39
44
  end
40
- end
41
45
 
42
- class NilClass
43
- # +nil+ is blank:
44
- #
45
- # nil.blank? # => true
46
- def blank?
47
- true
46
+ class NilClass
47
+ # +nil+ is blank:
48
+ #
49
+ # nil.blank? # => true
50
+ def blank?
51
+ true
52
+ end
48
53
  end
49
- end
50
54
 
51
- class FalseClass
52
- # +false+ is blank:
53
- #
54
- # false.blank? # => true
55
- def blank?
56
- true
55
+ class FalseClass
56
+ # +false+ is blank:
57
+ #
58
+ # false.blank? # => true
59
+ def blank?
60
+ true
61
+ end
57
62
  end
58
- end
59
63
 
60
- class TrueClass
61
- # +true+ is not blank:
62
- #
63
- # true.blank? # => false
64
- def blank?
65
- false
64
+ class TrueClass
65
+ # +true+ is not blank:
66
+ #
67
+ # true.blank? # => false
68
+ def blank?
69
+ false
70
+ end
66
71
  end
67
- end
68
72
 
69
- class Array
70
- # An array is blank if it's empty:
71
- #
72
- # [].blank? # => true
73
- # [1,2,3].blank? # => false
74
- alias_method :blank?, :empty?
75
- end
73
+ class Array
74
+ # An array is blank if it's empty:
75
+ #
76
+ # [].blank? # => true
77
+ # [1,2,3].blank? # => false
78
+ alias_method :blank?, :empty?
79
+ end
76
80
 
77
- class Hash
78
- # A hash is blank if it's empty:
79
- #
80
- # {}.blank? # => true
81
- # { key: 'value' }.blank? # => false
82
- alias_method :blank?, :empty?
83
- end
81
+ class Hash
82
+ # A hash is blank if it's empty:
83
+ #
84
+ # {}.blank? # => true
85
+ # { key: 'value' }.blank? # => false
86
+ alias_method :blank?, :empty?
87
+ end
84
88
 
85
- class String
86
- # A string is blank if it's empty or contains whitespaces only:
87
- #
88
- # ''.blank? # => true
89
- # ' '.blank? # => true
90
- # ' '.blank? # => true
91
- # ' something here '.blank? # => false
92
- def blank?
93
- self !~ /[^[:space:]]/
89
+ class String
90
+ # A string is blank if it's empty or contains whitespaces only:
91
+ #
92
+ # ''.blank? # => true
93
+ # ' '.blank? # => true
94
+ # ' '.blank? # => true
95
+ # ' something here '.blank? # => false
96
+ def blank?
97
+ self !~ /[^[:space:]]/
98
+ end
94
99
  end
95
- end
96
100
 
97
- class Numeric #:nodoc:
98
- # No number is blank:
99
- #
100
- # 1.blank? # => false
101
- # 0.blank? # => false
102
- def blank?
103
- false
101
+ class Numeric #:nodoc:
102
+ # No number is blank:
103
+ #
104
+ # 1.blank? # => false
105
+ # 0.blank? # => false
106
+ def blank?
107
+ false
108
+ end
104
109
  end
105
- end
110
+ end
@@ -0,0 +1,44 @@
1
+ module Yarder
2
+
3
+ # Basically a wrapper for a LogStash event that keeps track of if it was created from a rack
4
+ # middle-ware or not. This is important when it comes to deciding when to write the log
5
+ class Event
6
+
7
+ extend Forwardable
8
+ def_delegators :@logstash_event, :fields, :message=, :source=, :type=, :tags, :to_json
9
+
10
+ def initialize(logger, rack = false)
11
+ @logger = logger
12
+ @rack = rack
13
+ @logstash_event = LogStash::Event.new
14
+ end
15
+
16
+ def write(rack = false)
17
+ if @rack
18
+ @logger.info self if rack
19
+ else
20
+ @logger.info self
21
+ end
22
+ end
23
+
24
+ def add_tags_to_logger(request, tags)
25
+ tag_hash = []
26
+ if tags
27
+ tags.each do |tag|
28
+ case tag
29
+ when Symbol
30
+ tag_hash << {tag.to_s => request.send(tag) }
31
+ when Proc
32
+ tag_hash << tag.call(request)
33
+ else
34
+ tag_hash << tag
35
+ end
36
+ end
37
+ end
38
+
39
+ @logger.push_request_tags(tag_hash)
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -13,7 +13,7 @@ module Yarder
13
13
  t1 = Time.now
14
14
  request = ActionDispatch::Request.new(env)
15
15
 
16
- event = LogStash::Event.new
16
+ event = Yarder::Event.new(Rails.logger, true)
17
17
  event.message = "#{request.request_method} #{request.filtered_path} for #{request.ip}"
18
18
  event.fields['client_ip'] = request.ip
19
19
  event.fields['method'] = request.request_method
@@ -22,7 +22,7 @@ module Yarder
22
22
  event.source = "http://#{Socket.gethostname}#{request.filtered_path}"
23
23
  event.type = "rails_json_log"
24
24
 
25
- add_tags_to_logger(request) if @tags
25
+ event.add_tags_to_logger(request, @tags) if @tags
26
26
 
27
27
  Yarder.log_entries[Thread.current] = event
28
28
 
@@ -36,35 +36,17 @@ module Yarder
36
36
 
37
37
  ['rendering','sql'].each do |type|
38
38
  if event.fields[type] && !event.fields[type].empty?
39
- duration = event.fields[type].inject(0) {|result, event| result += event[:duration].to_f }
39
+ duration = event.fields[type].inject(0) {|result, local_event| result += local_event[:duration].to_f }
40
40
  event.fields["#{type}_duration"] = duration
41
41
  end
42
42
  end
43
43
 
44
- Rails.logger.info event
44
+ event.write(true)
45
45
  end
46
46
 
47
47
  Yarder.log_entries[Thread.current] = nil
48
48
  end
49
49
 
50
- def add_tags_to_logger(request)
51
- tags = []
52
- if @tags
53
- @tags.each do |tag|
54
- case tag
55
- when Symbol
56
- tags << {tag.to_s => request.send(tag) }
57
- when Proc
58
- tags << tag.call(request)
59
- else
60
- tags << tag
61
- end
62
- end
63
- end
64
-
65
- Rails.logger.push_request_tags(tags)
66
- end
67
-
68
50
  end
69
51
 
70
52
  end
@@ -20,10 +20,10 @@ module Yarder
20
20
  # This method is invoked when a log event occurs.
21
21
  def call(severity, timestamp, progname, msg)
22
22
  @entry = nil
23
- if msg.class == LogStash::Event
23
+ if msg.class == Yarder::Event
24
24
  @entry = msg
25
25
  else
26
- @entry = LogStash::Event.new
26
+ @entry = Yarder::Event.new(Rails.logger)
27
27
  @entry.message = msg
28
28
  end
29
29
  @entry.fields['severity'] = severity
@@ -99,4 +99,4 @@ module Yarder
99
99
  super if defined?(super)
100
100
  end
101
101
  end
102
- end
102
+ end
@@ -1,3 +1,3 @@
1
1
  module Yarder
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end