Class: SemanticLogger::Appender::Http

Inherits:
Subscriber show all
Defined in:
lib/semantic_logger/appender/http.rb

Overview

Log to any HTTP(S) server that accepts log messages in JSON form

Features:

  • JSON Formatted messages.

  • Uses a persistent http connection, if the server supports it.

  • SSL encryption (https).

Example:

SemanticLogger.add_appender(
  appender: :http,
  url:      'http://localhost:8088/path'
)

Direct Known Subclasses

Elasticsearch, SplunkHttp

Instance Attribute Summary collapse

Attributes inherited from Subscriber

#formatter

Attributes inherited from Base

#filter, #name

Instance Method Summary collapse

Methods inherited from Subscriber

#close, #flush, #level

Methods inherited from Base

#fast_tag, #level, #level=, #measure, #payload, #pop_tags, #push_tags, #silence, #tagged, #tags, #with_payload

Constructor Details

#initialize(options, &block) ⇒ Http

Create HTTP(S) log appender

Parameters:

url: [String]
  Valid URL to post to.
    Example: http://example.com/some_path
  To enable SSL include https in the URL.
    Example: https://example.com/some_path
    verify_mode will default: OpenSSL::SSL::VERIFY_PEER

application: [String]
  Name of this application to appear in log messages.
  Default: SemanticLogger.application

host: [String]
  Name of this host to appear in log messages.
  Default: SemanticLogger.host

username: [String]
  User name for basic Authentication.
  Default: nil ( do not use basic auth )

password: [String]
  Password for basic Authentication.

compress: [true|false]
  Whether to compress the JSON string with GZip.
  Default: false

ssl: [Hash]
  Specific SSL options: For more details see NET::HTTP.start
    ca_file, ca_path, cert, cert_store, ciphers, key, ssl_timeout,
    ssl_version, verify_callback, verify_depth and verify_mode.

level: [:trace | :debug | :info | :warn | :error | :fatal]
  Override the log level for this appender.
  Default: SemanticLogger.default_level

formatter: [Object|Proc]
  An instance of a class that implements #call, or a Proc to be used to format
  the output from this appender
  Default: Use the built-in formatter (See: #call)

filter: [Regexp|Proc]
  RegExp: Only include log messages where the class name matches the supplied.
  regular expression. All other messages will be ignored.
  Proc: Only include log messages where the supplied Proc returns true
        The Proc must return true or false.

open_timeout: [Float]
  Default: 2.0

read_timeout: [Float]
  Default: 1.0

continue_timeout: [Float]
  Default: 1.0

Raises:

  • (ArgumentError)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/semantic_logger/appender/http.rb', line 80

def initialize(options, &block)
  options           = options.dup
  @url              = options.delete(:url)
  @ssl_options      = options.delete(:ssl)
  @username         = options.delete(:username)
  @password         = options.delete(:password)
  @compress         = options.delete(:compress) || false
  @open_timeout     = options.delete(:open_timeout) || 2.0
  @read_timeout     = options.delete(:read_timeout) || 1.0
  @continue_timeout = options.delete(:continue_timeout) || 1.0

  raise(ArgumentError, 'Missing mandatory parameter :url') unless @url

  @header                     = {
    'Accept'       => 'application/json',
    'Content-Type' => 'application/json',
    # On Ruby v2.0 and greater, Net::HTTP.new already uses a persistent connection if the server allows it
    'Connection'   => 'keep-alive',
    'Keep-Alive'   => '300'
  }
  @header['Content-Encoding'] = 'gzip' if @compress

  uri     = URI.parse(@url)
  @server = uri.host
  raise(ArgumentError, "Invalid format for :url: #{@url.inspect}. Should be similar to: 'http://hostname:port/path'") unless @url

  @port     = uri.port
  @username = uri.user if !@username && uri.user
  @password = uri.password if !@password && uri.password
  @path     = uri.path

  if uri.scheme == 'https'
    @ssl_options               ||= {}
    @ssl_options[:use_ssl]     = true
    @ssl_options[:verify_mode] ||= OpenSSL::SSL::VERIFY_PEER
    @port                      ||= HTTP.https_default_port
  else
    @port ||= HTTP.http_default_port
  end
  @http = nil

  # Pass on the level and custom formatter if supplied
  super(options)
  reopen
end

Instance Attribute Details

#applicationObject

Returns the value of attribute application.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def application
  @application
end

#compressObject

Returns the value of attribute compress.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def compress
  @compress
end

#continue_timeoutObject

Returns the value of attribute continue_timeout.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def continue_timeout
  @continue_timeout
end

#headerObject

Returns the value of attribute header.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def header
  @header
end

#hostObject

Returns the value of attribute host.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def host
  @host
end

#httpObject (readonly)

Returns the value of attribute http.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def http
  @http
end

#open_timeoutObject

Returns the value of attribute open_timeout.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def open_timeout
  @open_timeout
end

#pathObject (readonly)

Returns the value of attribute path.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def path
  @path
end

#portObject (readonly)

Returns the value of attribute port.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def port
  @port
end

#read_timeoutObject

Returns the value of attribute read_timeout.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def read_timeout
  @read_timeout
end

#serverObject (readonly)

Returns the value of attribute server.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def server
  @server
end

#ssl_optionsObject (readonly)

Returns the value of attribute ssl_options.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def ssl_options
  @ssl_options
end

#urlObject (readonly)

Returns the value of attribute url.



21
22
23
# File 'lib/semantic_logger/appender/http.rb', line 21

def url
  @url
end

#usernameObject

Returns the value of attribute username.



19
20
21
# File 'lib/semantic_logger/appender/http.rb', line 19

def username
  @username
end

Instance Method Details

#log(log) ⇒ Object

Forward log messages to HTTP Server



151
152
153
154
155
# File 'lib/semantic_logger/appender/http.rb', line 151

def log(log)
  return false unless should_log?(log)

  post(formatter.call(log, self))
end

#reopenObject

Re-open after process fork



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/semantic_logger/appender/http.rb', line 127

def reopen
  # Close open connection if any
  begin
    @http.finish if @http
  rescue IOError
  end

  @http = Net::HTTP.new(server, port)

  if @ssl_options
    @http.methods.grep(/\A(\w+)=\z/) do |meth|
      key = $1.to_sym
      @ssl_options.key?(key) or next
      @http.__send__(meth, @ssl_options[key])
    end
  end

  @http.open_timeout     = @open_timeout
  @http.read_timeout     = @read_timeout
  @http.continue_timeout = @continue_timeout
  @http.start
end