loggerstash 0.0.8 → 0.0.9
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 +4 -4
- data/.editorconfig +7 -0
- data/.rubocop.yml +3 -0
- data/lib/loggerstash.rb +83 -91
- data/loggerstash.gemspec +3 -1
- metadata +8 -8
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f20d5ce8da4dbfec707d7b7ccd2dd6dba95a7f911980c3c4791e342a290034c0
         | 
| 4 | 
            +
              data.tar.gz: 5a335fdc5d9632439e9d75b3e141b5e09123b2de8d233acf70da8d5efee52a0c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a1e713734296868661da7ee81e9487dbce2173d41353abd9f9b665cb21e363d16929082fa1e4d5ab1c29b26075b7ae0126e9eaaec8c43b5dd57c57004084fc5b
         | 
| 7 | 
            +
              data.tar.gz: 2402ff129f1e76086a2f4c51bdc026f4a0a180b526644c70dd6ec7b595ef9e9324dc8c1852a36356a8a41c44c748cab170a0c0d1b102b74e207943e4aad95579
         | 
    
        data/.editorconfig
    ADDED
    
    
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/lib/loggerstash.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'logstash_writer'
         | 
| 2 4 | 
             
            require 'thread'
         | 
| 3 5 |  | 
| @@ -14,31 +16,29 @@ class Loggerstash | |
| 14 16 | 
             
              #
         | 
| 15 17 | 
             
              class AlreadyRunningError < Error; end
         | 
| 16 18 |  | 
| 17 | 
            -
              # Set the formatter proc to a new proc.
         | 
| 18 | 
            -
              #
         | 
| 19 | 
            -
              # The passed in proc must take four arguments: `severity`, `timestamp`,
         | 
| 20 | 
            -
              # `progname` and `message`.  `timestamp` is a `Time`, all over arguments
         | 
| 21 | 
            -
              # are `String`s, and `progname` can possibly be `nil`.  It must return a
         | 
| 22 | 
            -
              # Hash containing the parameters you wish to send to logstash.
         | 
| 23 | 
            -
              #
         | 
| 24 | 
            -
              attr_writer :formatter
         | 
| 25 | 
            -
             | 
| 26 19 | 
             
              # A new Loggerstash!
         | 
| 27 20 | 
             
              #
         | 
| 28 21 | 
             
              # @param logstash_server [String] an address:port, hostname:port, or srvname
         | 
| 29 22 | 
             
              #   to which a `json_lines` logstash connection can be made.
         | 
| 23 | 
            +
              #
         | 
| 30 24 | 
             
              # @param metrics_registry [Prometheus::Client::Registry] where the metrics
         | 
| 31 25 | 
             
              #   which are used by the underlying `LogstashWriter` should be registered,
         | 
| 32 26 | 
             
              #   for later presentation by the Prometheus client.
         | 
| 27 | 
            +
              #
         | 
| 33 28 | 
             
              # @param formatter [Proc] a formatting proc which takes the same arguments
         | 
| 34 29 | 
             
              #   as the standard `Logger` formatter, but rather than emitting a string,
         | 
| 35 30 | 
             
              #   it should pass back a Hash containing all the fields you wish to send
         | 
| 36 31 | 
             
              #   to logstash.
         | 
| 32 | 
            +
              #
         | 
| 37 33 | 
             
              # @param logstash_writer [LogstashWriter] in the event that you've already
         | 
| 38 34 | 
             
              #   got a LogstashWriter instance configured, you can pass it in here.  Note
         | 
| 39 35 | 
             
              #   that any values you've set for logstash_server and metrics_registry
         | 
| 40 36 | 
             
              #   will be ignored.
         | 
| 41 37 | 
             
              #
         | 
| 38 | 
            +
              # @param logger [Logger] passed to the LogstashWriter we create.  May or
         | 
| 39 | 
            +
              #   may not, itself, be attached to the Loggerstash for forwarding to
         | 
| 40 | 
            +
              #   logstash (Logception!).
         | 
| 41 | 
            +
              #
         | 
| 42 42 | 
             
              def initialize(logstash_server:, metrics_registry: nil, formatter: nil, logstash_writer: nil, logger: nil)
         | 
| 43 43 | 
             
                @logstash_server  = logstash_server
         | 
| 44 44 | 
             
                @metrics_registry = metrics_registry
         | 
| @@ -61,20 +61,21 @@ class Loggerstash | |
| 61 61 | 
             
              #   benefit from the attachment; that's up to you to ensure.
         | 
| 62 62 | 
             
              #
         | 
| 63 63 | 
             
              def attach(obj)
         | 
| 64 | 
            +
                run_writer
         | 
| 65 | 
            +
             | 
| 64 66 | 
             
                @op_mutex.synchronize do
         | 
| 65 | 
            -
                  obj.instance_variable_set(:@ | 
| 67 | 
            +
                  obj.instance_variable_set(:@logstash_writer, @logstash_writer)
         | 
| 68 | 
            +
                  obj.instance_variable_set(:@loggerstash_formatter, @formatter)
         | 
| 66 69 |  | 
| 67 70 | 
             
                  if obj.is_a?(Module)
         | 
| 68 71 | 
             
                    obj.prepend(Mixin)
         | 
| 69 72 | 
             
                  else
         | 
| 70 73 | 
             
                    obj.singleton_class.prepend(Mixin)
         | 
| 71 74 | 
             
                  end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                  run_writer
         | 
| 74 75 | 
             
                end
         | 
| 75 76 | 
             
              end
         | 
| 76 77 |  | 
| 77 | 
            -
              %i{logstash_server metrics_registry}.each do |sym|
         | 
| 78 | 
            +
              %i{formatter logger logstash_server metrics_registry}.each do |sym|
         | 
| 78 79 | 
             
                define_method(:"#{sym}=") do |v|
         | 
| 79 80 | 
             
                  @op_mutex.synchronize do
         | 
| 80 81 | 
             
                    if @logstash_writer
         | 
| @@ -86,111 +87,67 @@ class Loggerstash | |
| 86 87 | 
             
                end
         | 
| 87 88 | 
             
              end
         | 
| 88 89 |  | 
| 89 | 
            -
              # Send a logger message to logstash.
         | 
| 90 | 
            -
              #
         | 
| 91 | 
            -
              # @private
         | 
| 92 | 
            -
              #
         | 
| 93 | 
            -
              def log_message(s, t, p, m)
         | 
| 94 | 
            -
                @op_mutex.synchronize do
         | 
| 95 | 
            -
                  if @logstash_writer.nil?
         | 
| 96 | 
            -
                    #:nocov:
         | 
| 97 | 
            -
                    run_writer
         | 
| 98 | 
            -
                    #:nocov:
         | 
| 99 | 
            -
                  end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                  @logstash_writer.send_event((@formatter || default_formatter).call(s, t, p, m))
         | 
| 102 | 
            -
                end
         | 
| 103 | 
            -
              end
         | 
| 104 | 
            -
             | 
| 105 90 | 
             
              private
         | 
| 106 91 |  | 
| 107 92 | 
             
              # Do the needful to get the writer going.
         | 
| 108 93 | 
             
              #
         | 
| 109 | 
            -
              # This will error out unless the @op_mutex is held at the time the
         | 
| 110 | 
            -
              # method is called; we can't acquire it ourselves because some calls
         | 
| 111 | 
            -
              # to run_writer already need to hold the mutex.
         | 
| 112 | 
            -
              #
         | 
| 113 94 | 
             
              def run_writer
         | 
| 114 | 
            -
                 | 
| 115 | 
            -
                   | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
                       | 
| 126 | 
            -
             | 
| 127 | 
            -
                    if @logger
         | 
| 128 | 
            -
                      opts[:logger] = @logger
         | 
| 95 | 
            +
                @op_mutex.synchronize do
         | 
| 96 | 
            +
                  if @logstash_writer.nil?
         | 
| 97 | 
            +
                    {}.tap do |opts|
         | 
| 98 | 
            +
                      opts[:server_name] = @logstash_server
         | 
| 99 | 
            +
                      if @metrics_registry
         | 
| 100 | 
            +
                        opts[:metrics_registry] = @metrics_registry
         | 
| 101 | 
            +
                      end
         | 
| 102 | 
            +
                      if @logger
         | 
| 103 | 
            +
                        opts[:logger] = @logger
         | 
| 104 | 
            +
                      end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                      @logstash_writer = LogstashWriter.new(**opts)
         | 
| 107 | 
            +
                      @logstash_writer.start!
         | 
| 129 108 | 
             
                    end
         | 
| 130 | 
            -
             | 
| 131 | 
            -
                    @logstash_writer = LogstashWriter.new(**opts)
         | 
| 132 | 
            -
                    @logstash_writer.run
         | 
| 133 109 | 
             
                  end
         | 
| 134 110 | 
             
                end
         | 
| 135 111 | 
             
              end
         | 
| 136 112 |  | 
| 137 | 
            -
              # Mangle the standard sev/time/prog/msg set into a minimal logstash
         | 
| 138 | 
            -
              # event.
         | 
| 139 | 
            -
              #
         | 
| 140 | 
            -
              def default_formatter
         | 
| 141 | 
            -
                @default_formatter ||= ->(s, t, p, m) do
         | 
| 142 | 
            -
                  caller = caller_locations.find { |loc| ! [__FILE__, logger_filename].include? loc.absolute_path }
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                  {
         | 
| 145 | 
            -
                    "@timestamp":  t.utc.strftime("%FT%T.%NZ"),
         | 
| 146 | 
            -
                    "@metadata":   { event_type: "loggerstash" },
         | 
| 147 | 
            -
                    message:       m,
         | 
| 148 | 
            -
                    severity_name: s.downcase,
         | 
| 149 | 
            -
                    hostname:      Socket.gethostname,
         | 
| 150 | 
            -
                    pid:           $$,
         | 
| 151 | 
            -
                    thread_id:     Thread.current.object_id,
         | 
| 152 | 
            -
                    caller:        {
         | 
| 153 | 
            -
                      absolute_path: caller.absolute_path,
         | 
| 154 | 
            -
                      base_label:    caller.base_label,
         | 
| 155 | 
            -
                      label:         caller.label,
         | 
| 156 | 
            -
                      lineno:        caller.lineno,
         | 
| 157 | 
            -
                      path:          caller.path,
         | 
| 158 | 
            -
                    },
         | 
| 159 | 
            -
                  }.tap do |ev|
         | 
| 160 | 
            -
                    ev[:progname] = p if p
         | 
| 161 | 
            -
                  end
         | 
| 162 | 
            -
                end
         | 
| 163 | 
            -
              end
         | 
| 164 | 
            -
             | 
| 165 | 
            -
              # Identify the absolute path of the file that defines the Logger class.
         | 
| 166 | 
            -
              #
         | 
| 167 | 
            -
              def logger_filename
         | 
| 168 | 
            -
                @logger_filename ||= Logger.instance_method(:format_message).source_location.first
         | 
| 169 | 
            -
              end
         | 
| 170 | 
            -
             | 
| 171 113 | 
             
              # The methods needed to turn any Logger into a Loggerstash Logger.
         | 
| 172 114 | 
             
              #
         | 
| 173 115 | 
             
              module Mixin
         | 
| 116 | 
            +
                attr_writer :logstash_writer, :loggerstash_formatter
         | 
| 117 | 
            +
             | 
| 174 118 | 
             
                private
         | 
| 175 119 |  | 
| 176 120 | 
             
                # Hooking into this specific method may seem... unorthodox, but
         | 
| 177 121 | 
             
                # it seemingly has an extremely stable interface and is the most
         | 
| 178 122 | 
             
                # appropriate place to inject ourselves.
         | 
| 123 | 
            +
                #
         | 
| 179 124 | 
             
                def format_message(s, t, p, m)
         | 
| 180 | 
            -
                   | 
| 125 | 
            +
                  loggerstash_log_message(s, t, p, m)
         | 
| 181 126 |  | 
| 182 127 | 
             
                  super
         | 
| 183 128 | 
             
                end
         | 
| 184 129 |  | 
| 185 | 
            -
                #  | 
| 130 | 
            +
                # Send a logger message to logstash.
         | 
| 131 | 
            +
                #
         | 
| 132 | 
            +
                def loggerstash_log_message(s, t, p, m)
         | 
| 133 | 
            +
                  logstash_writer.send_event(loggerstash_formatter.call(s, t, p, m))
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                # The current formatter for logstash-destined messages.
         | 
| 137 | 
            +
                #
         | 
| 138 | 
            +
                def loggerstash_formatter
         | 
| 139 | 
            +
                  @loggerstash_formatter ||= self.class.ancestors.find { |m| m.instance_variable_defined?(:@loggerstash_formatter) }.instance_variable_get(:@loggerstash_formatter) || default_loggerstash_formatter
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                # Find the relevant logstash_writer for this Logger.
         | 
| 186 143 | 
             
                #
         | 
| 187 144 | 
             
                # We're kinda reimplementing Ruby's method lookup logic here, but there's
         | 
| 188 145 | 
             
                # no other way to store our object *somewhere* in the object + class
         | 
| 189 146 | 
             
                # hierarchy and still be able to get at it from a module (class variables
         | 
| 190 | 
            -
                # don't like being accessed from modules).
         | 
| 191 | 
            -
                #
         | 
| 192 | 
            -
                def  | 
| 193 | 
            -
                   | 
| 147 | 
            +
                # don't like being accessed from modules).  This is necessary because you
         | 
| 148 | 
            +
                # can attach Loggerstash to the Logger class, not just to an instance.
         | 
| 149 | 
            +
                def logstash_writer
         | 
| 150 | 
            +
                  @logstash_writer ||= self.class.ancestors.find { |m| m.instance_variable_defined?(:@logstash_writer) }.instance_variable_get(:@logstash_writer).tap do |ls|
         | 
| 194 151 | 
             
                    if ls.nil?
         | 
| 195 152 | 
             
                      #:nocov:
         | 
| 196 153 | 
             
                      raise RuntimeError,
         | 
| @@ -199,5 +156,40 @@ class Loggerstash | |
| 199 156 | 
             
                    end
         | 
| 200 157 | 
             
                  end
         | 
| 201 158 | 
             
                end
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                # Mangle the standard sev/time/prog/msg set into a logstash
         | 
| 161 | 
            +
                # event.
         | 
| 162 | 
            +
                #
         | 
| 163 | 
            +
                def default_loggerstash_formatter
         | 
| 164 | 
            +
                  ->(s, t, p, m) do
         | 
| 165 | 
            +
                    caller = caller_locations.find { |loc| ! [__FILE__, logger_filename].include? loc.absolute_path }
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                    {
         | 
| 168 | 
            +
                      "@timestamp":  t.utc.strftime("%FT%T.%NZ"),
         | 
| 169 | 
            +
                      "@metadata":   { event_type: "loggerstash" },
         | 
| 170 | 
            +
                      message:       m,
         | 
| 171 | 
            +
                      severity_name: s.downcase,
         | 
| 172 | 
            +
                      hostname:      Socket.gethostname,
         | 
| 173 | 
            +
                      pid:           $$,
         | 
| 174 | 
            +
                      thread_id:     Thread.current.object_id,
         | 
| 175 | 
            +
                      caller:        {
         | 
| 176 | 
            +
                        absolute_path: caller.absolute_path,
         | 
| 177 | 
            +
                        base_label:    caller.base_label,
         | 
| 178 | 
            +
                        label:         caller.label,
         | 
| 179 | 
            +
                        lineno:        caller.lineno,
         | 
| 180 | 
            +
                        path:          caller.path,
         | 
| 181 | 
            +
                      },
         | 
| 182 | 
            +
                    }.tap do |ev|
         | 
| 183 | 
            +
                      ev[:progname]    = p if p
         | 
| 184 | 
            +
                      ev[:thread_name] = Thread.current.name if Thread.current.name
         | 
| 185 | 
            +
                    end
         | 
| 186 | 
            +
                  end
         | 
| 187 | 
            +
                end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                # Identify the absolute path of the file that defines the Logger class.
         | 
| 190 | 
            +
                #
         | 
| 191 | 
            +
                def logger_filename
         | 
| 192 | 
            +
                  @logger_filename ||= Logger.instance_method(:format_message).source_location.first
         | 
| 193 | 
            +
                end
         | 
| 202 194 | 
             
              end
         | 
| 203 195 | 
             
            end
         | 
    
        data/loggerstash.gemspec
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            begin
         | 
| 2 4 | 
             
              require 'git-version-bump'
         | 
| 3 5 | 
             
            rescue LoadError
         | 
| @@ -27,7 +29,7 @@ Gem::Specification.new do |s| | |
| 27 29 |  | 
| 28 30 | 
             
              s.required_ruby_version = ">= 2.3.0"
         | 
| 29 31 |  | 
| 30 | 
            -
              s.add_runtime_dependency "logstash_writer", " | 
| 32 | 
            +
              s.add_runtime_dependency "logstash_writer", ">= 0.0.11"
         | 
| 31 33 |  | 
| 32 34 | 
             
              s.add_development_dependency 'bundler'
         | 
| 33 35 | 
             
              s.add_development_dependency 'github-release'
         | 
    
        metadata
    CHANGED
    
    | @@ -1,29 +1,29 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: loggerstash
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.9
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Matt Palmer
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2019-07-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: logstash_writer
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - - " | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            -
                    version:  | 
| 19 | 
            +
                    version: 0.0.11
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - - " | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 26 | 
            +
                    version: 0.0.11
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: bundler
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -202,6 +202,7 @@ executables: [] | |
| 202 202 | 
             
            extensions: []
         | 
| 203 203 | 
             
            extra_rdoc_files: []
         | 
| 204 204 | 
             
            files:
         | 
| 205 | 
            +
            - ".editorconfig"
         | 
| 205 206 | 
             
            - ".gitignore"
         | 
| 206 207 | 
             
            - ".rubocop.yml"
         | 
| 207 208 | 
             
            - ".travis.yml"
         | 
| @@ -230,8 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 230 231 | 
             
                - !ruby/object:Gem::Version
         | 
| 231 232 | 
             
                  version: '0'
         | 
| 232 233 | 
             
            requirements: []
         | 
| 233 | 
            -
             | 
| 234 | 
            -
            rubygems_version: 2.7.7
         | 
| 234 | 
            +
            rubygems_version: 3.0.1
         | 
| 235 235 | 
             
            signing_key: 
         | 
| 236 236 | 
             
            specification_version: 4
         | 
| 237 237 | 
             
            summary: Monkeypatch Logger to send log entries to logstash
         |