Skip to content
This repository was archived by the owner on Nov 4, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 7 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# IrusAnalytics

IrusAnalytics is a gem that provides a simple way to send analytics to the IRUS repository aggregation service.
IrusAnalytics is a gem that provides a simple way to send analytics to the IRUS repository aggregation service.

More information about IRUS can be found at [https://irus.jisc.ac.uk/r5/](https://irus.jisc.ac.uk/r5/). In summary the IRUS service is designed to provide item-level usage statistics, both for Investigations (views) and Requests (downloads), for Institutional Repositories. To sign up and use IRUS, please see the above link.
More information about IRUS can be found at [https://irus.jisc.ac.uk/r5/](https://irus.jisc.ac.uk/r5/). In summary the IRUS service is designed to provide item-level usage statistics, both for Investigations (views) and Requests (downloads), for Institutional Repositories. To sign up and use IRUS, please see the above link.

This gem was developed for use with a Hyrax repository [http://samvera.org/](http://samvera.org/), but it can be used with any other web application supporting Ruby gems.
This gem was developed for use with a Hyrax repository [http://samvera.org/](http://samvera.org/), but it can be used with any other web application supporting Ruby gems.

More information on COUNTER reports and reporting can be found at [Project COUNTER](https://www.projectcounter.org/)

Expand Down Expand Up @@ -51,7 +51,7 @@ This uses a similar mechanism to the standard rails database.yml file to allow f
is used to define the IRUS server endpoint, this can be configured for the test version of the service.

**robots_file**\
is used to specify the name of the file containing the robot UserAgents as regular expressions.
is used to specify the name of the file containing the robot UserAgents as regular expressions.

**Example installed file**

Expand Down Expand Up @@ -211,8 +211,8 @@ end

Therefore in summary...

include IrusAnalytics::Controller::AnalyticsBehaviour
include IrusAnalytics::Controller::AnalyticsBehaviour

after_filter :send_analytics, only: [:show]

def item_identifier_for_irus_analytics
Expand All @@ -223,19 +223,7 @@ Therefore in summary...

NOTE: If you are not using the [Blacklight OAI Provider](https://github.com/projectblacklight/blacklight_oai_provider) gem to create your OAI feed, you'll need to modify the `item_identifier_for_irus_analytics` method to conform with your application's [OAI identifiers](http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm).

To be compliant with the IRUS client requirements/recommendations this Gem makes use of the Resque [https://github.com/resque/resque](https://github.com/resque/resque). Resque provides a simple way to create background jobs within your Ruby application, and is specifically used within this gem to push the analytics posts onto a queue. This means the download functionality within your application is unaffected by the send analytics call, and it provides a means of queuing analytics if the IRUS server is down.

Note: Resque requires Redis to be installed

By installing this gem, your application should have access to the Resque rake tasks. These can be seen by running "rake -T", the list should include:-

rake resque:failures:sort
rake resque:work
rake resque:workers

To start the resque background job for this gem use

QUEUE=irus_analytics rake environment resque:work
To be compliant with the IRUS client requirements/recommendations this Gem makes use of the ActiveJob. Any working ActiveJob adapter should work for the processing of the background jobs and is specifically used within this gem to push the analytics posts onto a queue. This means the download functionality within your application is unaffected by the send analytics call, and it provides a means of queuing analytics if the IRUS server is down.

## Additional Notes for Hyrax

Expand Down
1 change: 0 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require "resque/tasks"

# Default directory to look in is `/specs`
# Run with `rake spec`
Expand Down
2 changes: 1 addition & 1 deletion config/locales/irus_analytics.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ en:
exited: '%{method} exited'
no_server_address: No server address
params_extracted: '%{method} parameters extracted'
enquing_error: 'Problem enqueing the analytics with Resque. Error: %{error}'
enquing_error: 'Problem enqueing the analytics job. Error: %{error}'
tracker_context:
# These transport layer codes don't belong here, see irus_analytics/elements.rb
# handles: # see: https://irus.jisc.ac.uk/r5/about/policies/tracker/
Expand Down
2 changes: 1 addition & 1 deletion irus_analytics.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]

spec.add_dependency "openurl" # https://github.com/openurl/openurl
spec.add_dependency "resque"
spec.add_dependency "activejob"
spec.add_dependency 'config_files' # https://github.com/blackrat/config_files
spec.add_dependency 'i18n'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ en:
exited: '%{method} exited'
no_server_address: No server address
params_extracted: '%{method} parameters extracted'
enquing_error: 'Problem enqueing the analytics with Resque. Error: %{error}'
enquing_error: 'Problem enqueing the analytics with background job. Error: %{error}'
tracker_context:
# These transport layer codes don't belong here, see irus_analytics/elements.rb
# handles: # see: https://irus.jisc.ac.uk/r5/about/policies/tracker/
Expand Down
2 changes: 1 addition & 1 deletion lib/irus_analytics.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require "resque/server"
require 'irus_analytics/elements'
require 'active_job'
require 'irus_analytics/irus_analytics_logger'
if defined?(Rails)
require 'rails/generators'
Expand Down
6 changes: 6 additions & 0 deletions lib/irus_analytics/application_job_fallback.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

unless defined?(ApplicationJob)
class ApplicationJob < ActiveJob::Base
end
end
12 changes: 7 additions & 5 deletions lib/irus_analytics/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ class << self

define_method name do
rv = nil
if defined?( Settings ) && Settings.hostname.present?
if irus_analytics_config[Rails.env][:named_servers].present?
named_server = Settings.hostname
rv = irus_analytics_config[Rails.env][named_server][name.to_s]
end
# Handle multi-tenant hyku _and_ hyrax, both of them using the named_servers section of the config file
if irus_analytics_config[Rails.env]['named_servers'].present?
# hyrax?
named_server = Settings.hostname if defined?( Settings ) && Settings.hostname.present?
# hyku?
named_server = Site.account.cname if defined?( Site ) && Site.account&.cname.present?
rv = irus_analytics_config[Rails.env][named_server][name.to_s] if irus_analytics_config[Rails.env][named_server].present?
end
rv = irus_analytics_config[Rails.env][name.to_s] if rv.blank?
rv
Expand Down
3 changes: 1 addition & 2 deletions lib/irus_analytics/controller/analytics_behaviour.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# frozen_string_literal: true

require 'logger'
require 'resque'
require 'active_support/core_ext/module/delegation'
require 'irus_analytics/configuration'
require 'irus_analytics/irus_analytics_logger'
Expand Down Expand Up @@ -123,7 +122,7 @@ def enqueue
"@identifier=#{@identifier}",
"@usage_event_type=#{@usage_event_type}",
"" ] if verbose_debug
Resque.enqueue(IrusClient, server, params, @usage_event_type)
IrusClient.perform_later(server, params, @usage_event_type)
rescue Exception => e
logger.error(%Q(#{I18n.t('.error', method: debugger_method, scope: i18n_scope)}:#{I18n.t('.enquing_error', error: e, scope: i18n_scope)}))
end
Expand Down
38 changes: 19 additions & 19 deletions lib/irus_analytics/irus_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@

require 'active_support/core_ext/hash/keys'
require_relative './irus_analytics_logger'
require_relative './application_job_fallback'

module IrusAnalytics
class IrusClient
@queue = :irus_analytics
class IrusClient < ApplicationJob

class << self
def perform(irus_server_address, analytics_params, usage_event_type)
DebugLogger.bold_debug [ DebugLogger.here,
DebugLogger.called_from,
"irus_server_address=#{irus_server_address}",
"analytics_params=#{analytics_params}",
"usage_event_type=#{usage_event_type}",
"" ] if DebugLogger.verbose_debug
service = IrusAnalytics::IrusAnalyticsService.new(irus_server_address)
case usage_event_type
when REQUEST
service.send_analytics_request(analytics_params.deep_symbolize_keys)
when INVESTIGATION
service.send_analytics_investigation(analytics_params.deep_symbolize_keys)
else
service.send_analytics(analytics_params.deep_symbolize_keys)
end
queue_as :irus_analytics

def perform(irus_server_address, analytics_params, usage_event_type)
DebugLogger.bold_debug [ DebugLogger.here,
DebugLogger.called_from,
"irus_server_address=#{irus_server_address}",
"analytics_params=#{analytics_params}",
"usage_event_type=#{usage_event_type}",
"" ] if DebugLogger.verbose_debug
service = IrusAnalytics::IrusAnalyticsService.new(irus_server_address)
case usage_event_type
when REQUEST
service.send_analytics_request(analytics_params.deep_symbolize_keys)
when INVESTIGATION
service.send_analytics_investigation(analytics_params.deep_symbolize_keys)
else
service.send_analytics(analytics_params.deep_symbolize_keys)
end
end
end
Expand Down
4 changes: 0 additions & 4 deletions lib/irus_analytics/rail_tie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,5 @@ module IrusAnalytics
class Railtie < Rails::Railtie
railtie_name :irus_analytics

rake_tasks do
load "tasks/resque.rake"
end

end
end
3 changes: 0 additions & 3 deletions lib/tasks/resque.rake

This file was deleted.

32 changes: 19 additions & 13 deletions spec/lib/irus_analytics/controller/analytics_behaviour_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ def skip_send_irus_analytics?(_usage_event_type)
http_referer: "http://localhost:3000",
source_repository: "hydra.hull.ac.uk"
}
allow(Resque).to receive(:enqueue) .and_return(nil)
# Should NOT filter this request
expect(@test_class).to receive(:filter_request?).and_return(false)
expect(Resque).to receive(:enqueue).with(IrusAnalytics::IrusClient,
"irus-server-address.org",
params, IrusAnalytics::REQUEST )
expect(IrusAnalytics::IrusClient).to receive(:perform_later).with(
"irus-server-address.org",
params,
IrusAnalytics::REQUEST
).and_return(nil)
@test_class.send_irus_analytics
end

Expand All @@ -64,14 +65,13 @@ def skip_send_irus_analytics?(_usage_event_type)
http_referer: "http://localhost:3000",
source_repository: "hydra.hull.ac.uk"
}
allow(Resque).to receive(:enqueue).and_return(nil)
expect(@test_class).to_not receive(:filter_request?)
expect(Resque).to_not receive(:enqueue)
expect(IrusAnalytics::IrusClient).to_not receive(:perform_later)
@test_class.send_irus_analytics
end

it "will not call the send_irus_analytics method when there is a filter user-agent.." do
# Add a well known robot...
# Add a well known robot...
@test_class.request = double("request", :remote_ip => "127.0.0.1", :user_agent => "Microsoft URL Control - 6.00.8862", url: "http://localhost:3000/test", referer: "http://localhost:3000", headers: { "HTTP_RANGE" => nil })
# We set the datetime stamp to ensure sync
date_time = "2014-06-09T16:56:48Z"
Expand All @@ -81,15 +81,18 @@ def skip_send_irus_analytics?(_usage_event_type)
params = { date_stamp: date_time, client_ip_address: "127.0.0.1", user_agent: "Microsoft URL Control - 6.00.8862" ,item_oai_identifier: "test:123",
file_url: "http://localhost:3000/test", http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" }

allow(Resque).to receive(:enqueue) .and_return(nil)
# Should filter this request
expect(Resque).to_not receive(:enqueue).with(IrusAnalytics::IrusClient, "irus-server-address.org", params )
expect(IrusAnalytics::IrusClient).to_not receive(:perform_later).with(
"irus-server-address.org",
params
)

@test_class.send_irus_analytics
end


it "will not call the send_irus_analytics method when the request is expecting a chunk of data (HTTP_RANGE downloading data)." do
# Add a well known robot...
# Add a well known robot...
@test_class.request = double("request", :remote_ip => "127.0.0.1", :user_agent =>"Test user agent", url: "http://localhost:3000/test", referer: "http://localhost:3000", headers: { "HTTP_RANGE" => "bytes=0-65535"})
# We set the datetime stamp to ensure sync
date_time = "2014-06-09T16:56:48Z"
Expand All @@ -99,12 +102,15 @@ def skip_send_irus_analytics?(_usage_event_type)
params = { date_stamp: date_time, client_ip_address: "127.0.0.1", user_agent: "Microsoft URL Control - 6.00.8862" ,item_oai_identifier: "test:123",
file_url: "http://localhost:3000/test", http_referer: "http://localhost:3000", source_repository: "hydra.hull.ac.uk" }

allow(Resque).to receive(:enqueue) .and_return(nil)
# Should filter this request
expect(Resque).to_not receive(:enqueue).with(IrusAnalytics::IrusClient, "irus-server-address.org", params )
expect(IrusAnalytics::IrusClient).to_not receive(:perform_later).with(
"irus-server-address.org",
params
)

@test_class.send_irus_analytics
end


end
end
end