Class: Clickstream::Capture

Inherits:
Object
  • Object
show all
Includes:
Rack::Utils
Defined in:
lib/clickstream/capture.rb

Constant Summary collapse

FORMAT =
%{[Clickstream #{Clickstream::VERSION}] [%s] %s - %s "%s%s %s\n}
'clickstream.io'.freeze
Regexp.new("#{COOKIE_NAME}=([^;]*)").freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, opts = {}) ⇒ Capture

Returns a new instance of Capture.

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/clickstream/capture.rb', line 16

def initialize(app, opts={})
  @app = app
  # Options
  @capture          = !!opts[:capture]
  @bench            = opts[:capture] && opts[:bench]
  capture_crawlers  = opts[:capture_crawlers]
  crawlers          = opts[:crawlers] || "(Baidu|Gigabot|Googlebot|libwww-perl|lwp-trivial|msnbot|SiteUptime|Slurp|WordPress|ZIBB|ZyBorg|bot|crawler|spider|robot|crawling|facebook|w3c|coccoc|Daumoa|panopta)"
  api_key           = opts[:api_key]
  api_uri           = opts[:api_uri]
  @filter_params    = opts[:filter_params] || []
  @filter_uri       = opts[:filter_uri] || []

  filter_params.concat(Rails.configuration.filter_parameters || []) if defined?(Rails)

  Clickstream.logger = opts[:logger] if opts[:logger]

  raise ArgumentError, 'API key missing.' if api_key.nil?

  @inspector = Clickstream::Inspector.new api_key, api_uri, crawlers, capture_crawlers, filter_params

  @client = {}
  Clickstream::APIClient.new(api_key, api_uri).handshake { |k, v| @client[k] = v}
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



10
11
12
# File 'lib/clickstream/capture.rb', line 10

def client
  @client
end

#filter_paramsObject (readonly)

Returns the value of attribute filter_params.



10
11
12
# File 'lib/clickstream/capture.rb', line 10

def filter_params
  @filter_params
end

#filter_uriObject (readonly)

Returns the value of attribute filter_uri.



10
11
12
# File 'lib/clickstream/capture.rb', line 10

def filter_uri
  @filter_uri
end

Instance Method Details

#_call(env) ⇒ Object



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
# File 'lib/clickstream/capture.rb', line 44

def _call(env)
  start_processing = Time.now
  status, headers, response = @app.call(env)
  stop_processing = Time.now

  start = Time.now if @bench

  headers = HeaderHash.new(headers)

  if @capture && !STATUS_WITH_NO_ENTITY_BODY.include?(status) && !headers['transfer-encoding'] && headers['content-type'] && (
    headers['content-type'].include?('text/html') || headers['content-type'].include?('application/json') ||
        headers['content-type'].include?('application/xml') || headers['content-type'].include?('text/javascript') ||
        headers['content-type'].include?('text/plain')
  ) && !filtered_uri?(env['REQUEST_URI'])

    cookie = session_cookie(env, headers)
    pid = SecureRandom.uuid
    body = response.clone

    Thread.abort_on_exception = false
    Thread.new do
      begin
        result = @inspector.investigate env, status, headers, body, start_processing, stop_processing, cookie, pid
        log env, result
      rescue Exception => e
        log_error env, e
      end
    end

    response = insert_js(response, headers, cookie, pid) if headers['content-type'].include?('text/html') #&& headers['content-length'].to_i > 0
  end

  if @bench
    stop = Time.now
    duration = ((stop-start) * 1000).round(3)
    headers['Clickstream'] = "version #{Clickstream::VERSION}, time #{duration}ms"
    Thread.new { log(env, "Time: #{duration}ms") }
  end

  [status, headers, response]
end

#call(env) ⇒ Object



40
41
42
# File 'lib/clickstream/capture.rb', line 40

def call(env)
  dup._call(env)
end