Class: Le::Host::HTTP

Inherits:
Object
  • Object
show all
Includes:
InstanceMethods
Defined in:
lib/le/host/http.rb

Constant Summary collapse

API_SERVER =
'data.logentries.com'
DATA_ENDPOINT =
'data.logentries.com'
DATA_PORT_UNSECURE =
80
DATA_PORT_SECURE =
443
API_PORT =
10000
API_SSL_PORT =
20000
SHUTDOWN_COMMAND =

magic command string for async worker to shutdown

"DIE!DIE!"
SHUTDOWN_MAX_WAIT =

max seconds to wait for queue to clear on shutdown

10
SHUTDOWN_WAIT_STEP =

sleep duration (seconds) while waiting to shutdown

0.2

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from InstanceMethods

#format_message, #formatter

Constructor Details

#initialize(token, local, debug, ssl, datahub_endpoint, host_id, custom_host, udp_port, use_data_endpoint) ⇒ HTTP

Returns a new instance of HTTP.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
# File 'lib/le/host/http.rb', line 26

def initialize(token, local, debug, ssl, datahub_endpoint, host_id, custom_host, udp_port, use_data_endpoint)
    if local
      device = if local.class <= TrueClass
        if defined?(Rails)
          Rails.root.join("log","#{Rails.env}.log")
        else
          STDOUT
        end
      else
      local
      end
    @logger_console = Logger.new(device)
    end

    @local = !!local
    @debug= debug
    @ssl = ssl
    @udp_port = udp_port
    @use_data_endpoint = use_data_endpoint

  @datahub_endpoint = datahub_endpoint
  if !@datahub_endpoint[0].empty?
    @datahub_enabled=true
    @datahub_ip="#{@datahub_endpoint[0]}"
    @datahub_port=@datahub_endpoint[1]
  else
    @datahub_enabled=false
  end


  if (@datahub_enabled && @ssl)
    puts ("\n\nYou Cannot have DataHub and SSL enabled at the same time.  Please set SSL value to false in your environment.rb file or used Token-Based logging by leaving the Datahub IP address blank. Exiting application. \n\n")
    exit
  end


 #check if DataHub is enabled... if datahub is not enabled, set the token to the token's parameter.  If DH is enabled, make the token empty.
  if (!datahub_enabled)
     @token = token
  else
    @token = ''

 #! NOTE THIS @datahub_port conditional MAY NEED TO BE CHANGED IF SSL CAN'T WORK WITH DH
    @datahub_port = @datahub_port.empty? ?  API_SSL_PORT : datahub_port
    @datahub_ip = datahub_ip
  end

  @host_name_enabled=custom_host[0];
  @host_name= custom_host[1];


# Check if host_id is empty -- if not assign, if so, make it an empty string.
 if !host_id.empty?
    @host_id = host_id
    @host_id = "host_id=#{host_id}"
  else
    @host_id=''
  end



#assign host_name, if no host name is given and host_name_enabled = true... assign a host_name based on the machine name.
 if @host_name_enabled
    if host_name.empty?
      @host_name=Socket.gethostname
    end

    @host_name="host_name=#{@host_name}"
  end


  @queue = Queue.new
  @started = false
  @thread = nil

  if @debug
    self.init_debug
  end
  at_exit { shutdown! }
end

Instance Attribute Details

#connObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def conn
  @conn
end

#custom_hostObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def custom_host
  @custom_host
end

#datahub_enabledObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def datahub_enabled
  @datahub_enabled
end

#datahub_endpointObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def datahub_endpoint
  @datahub_endpoint
end

#datahub_ipObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def datahub_ip
  @datahub_ip
end

#datahub_portObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def datahub_port
  @datahub_port
end

#debugObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def debug
  @debug
end

#host_idObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def host_id
  @host_id
end

#host_nameObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def host_name
  @host_name
end

#host_name_enabledObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def host_name_enabled
  @host_name_enabled
end

#localObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def local
  @local
end

#queueObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def queue
  @queue
end

#sslObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def ssl
  @ssl
end

#startedObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def started
  @started
end

#threadObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def thread
  @thread
end

#tokenObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def token
  @token
end

#udp_portObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def udp_port
  @udp_port
end

#use_data_endpointObject

! attr_accessor :token, :queue, :started, :thread, :conn, :local, :debug, :ssl, :datahub_enabled, :dathub_ip, :datahub_port, :host_id, :custom_host, :host_name_enabled, :host_name



23
24
25
# File 'lib/le/host/http.rb', line 23

def use_data_endpoint
  @use_data_endpoint
end

Instance Method Details

#check_async_threadObject



155
156
157
158
159
# File 'lib/le/host/http.rb', line 155

def check_async_thread
  if not(@thread && @thread.alive?)
    @thread = Thread.new { run() }
  end
end

#closeObject



161
162
163
164
# File 'lib/le/host/http.rb', line 161

def close
  dbg "LE: Closing asynchronous socket writer"
  @started = false
end

#closeConnectionObject



248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/le/host/http.rb', line 248

def closeConnection
  begin
    if @conn.respond_to?(:sysclose)
      @conn.sysclose
    elsif @conn.respond_to?(:close)
      @conn.close
    end
  rescue
    dbg "LE: couldn't close connection, close with exception - #{ $! }"
  ensure
    @conn = nil
  end
end

#dbg(message) ⇒ Object



115
116
117
118
119
# File 'lib/le/host/http.rb', line 115

def dbg(message)
  if @debug
    @debug_logger.add(Logger::Severity::DEBUG, message)
  end
end

#init_debugObject



107
108
109
110
111
112
113
# File 'lib/le/host/http.rb', line 107

def init_debug
  filePath = "logentriesGem.log"
  if File.exist?('log/')
    filePath = "log/logentriesGem.log"
  end
  @debug_logger = Logger.new(filePath)
end

#openConnectionObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/le/host/http.rb', line 166

def openConnection
  dbg "LE: Reopening connection to Logentries API server"

  if @use_data_endpoint
      host = DATA_ENDPOINT
      if @ssl
        port = DATA_PORT_SECURE
      else
        port = DATA_PORT_UNSECURE
      end
  else
    if @udp_port
      host = API_SERVER
      port = @udp_port
    elsif @datahub_enabled
      host = @datahub_ip
      port = @datahub_port
    else
      host = API_SERVER
      port = @ssl ? API_SSL_PORT: API_PORT
    end
  end

  if @udp_port
    @conn = UDPSocket.new
    @conn.connect(host, port)
  else
    socket = TCPSocket.new(host, port)

    if @ssl
	    cert_store = OpenSSL::X509::Store.new
	    cert_store.set_default_paths

      ssl_context = OpenSSL::SSL::SSLContext.new()
	    ssl_context.cert_store = cert_store

      ssl_version_candidates = [:TLSv1_2, :TLSv1_1, :TLSv1]
      ssl_version_candidates = ssl_version_candidates.select { |version| OpenSSL::SSL::SSLContext::METHODS.include? version }
      if ssl_version_candidates.empty?
          raise "Could not find suitable TLS version"
      end
	    # currently we only set the version when we have no choice
      ssl_context.ssl_version = ssl_version_candidates[0] if ssl_version_candidates.length == 1
      ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
      ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
      ssl_socket.hostname = host if ssl_socket.respond_to?(:hostname=)
      ssl_socket.sync_close = true
      Timeout::timeout(10) do
        ssl_socket.connect
      end
      @conn = ssl_socket
    else
      @conn = socket
    end
  end

  dbg "LE: Connection established"
end

#reopenConnectionObject



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/le/host/http.rb', line 225

def reopenConnection
  closeConnection
  root_delay = 0.1
  loop do
    begin
      openConnection
      break
    rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, EOFError
      dbg "LE: Unable to connect to Logentries due to timeout(#{ $! })"
    rescue
      dbg "LE: Got exception in reopenConnection - #{ $! }"
      raise
    end
    root_delay *= 2
    if root_delay >= 10
      root_delay = 10
    end
    wait_for = (root_delay + rand(root_delay)).to_i
    dbg "LE: Waiting for #{ wait_for }ms"
    sleep(wait_for)
  end
end

#runObject



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/le/host/http.rb', line 262

def run
  reopenConnection

  loop do
    data = @queue.pop
    break if data == SHUTDOWN_COMMAND
    loop do
      begin
        @conn.write(data)
      rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, EOFError
        dbg "LE: Connection timeout(#{ $! }), try to reopen connection"
        reopenConnection
        next
      rescue
        dbg("LE: Got exception in run loop - #{ $! }")
        raise
      end

      break
    end
  end

  dbg "LE: Closing Asynchronous socket writer"

  closeConnection
end

#start_async_threadObject



149
150
151
152
153
# File 'lib/le/host/http.rb', line 149

def start_async_thread
  @thread = Thread.new { run() }
  dbg "LE: Asynchronous socket writer started"
  @started = true
end

#write(message) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/le/host/http.rb', line 121

def write(message)

  if !host_id.empty?
    message = "#{message} #{ host_id }"
  end

  if host_name_enabled
    message="#{message} #{ host_name }"
  end

  if @local
    @logger_console.add(Logger::Severity::UNKNOWN, message)
  end

  if message.scan(/\n/).empty?
    @queue << "#{ @token } #{ message } \n"
  else
    @queue << "#{ message.gsub(/^/, "#{ @token } [#{ random_message_id }]") }\n"
  end


  if @started
    check_async_thread
  else
    start_async_thread
  end
end