Эффективный способ отслеживать даты входа пользователя и историю IP-адресов

Я пытаюсь отследить историю входа пользователей в статистику, но мне не ясно, как лучше всего это сделать. У меня могла бы быть отдельная таблица, которая записывает пользователей и их статистику входа в систему с датой, но эта таблица может стать ДЕЙСТВИТЕЛЬНО большой. Я мог бы отследить некоторые исторические поля в самой модели / объекте User в поле для разбора и просто обновить его (их) в некотором формате строки с разделителями. например, разделить на: получить последний, если включенный код даты не сегодня, добавить элемент (дата + счет), иначе увеличить, а затем сохранить его обратно. По крайней мере, с этим вторым подходом было бы легко удалить старые элементы (например, хранить только 30 дней ежедневных входов в систему или IP-адреса), поскольку отдельная таблица потребовала бы задачи для удаления старых записей.

Я большой поклонник мгновенных изменений. Задачи полезны, но могут усложнить ситуацию по причинам обслуживания.

У кого-нибудь есть предложения? У меня нет решения для кэширования внешних данных или чего-то еще. Любые указатели также приветствуются! (Я искал похожие вопросы и ответы)

Спасибо!

7 ответов

Решение

Я ненавижу отвечать на мои собственные вопросы, особенно учитывая, что вы оба дали полезные ответы. Я думаю, что ответ на мой вопрос с подходом, который я выбрал, может помочь другим, в сочетании с вашими ответами.

Я играл с импрессионистским Gem (единственный полезный Gem для просмотра страниц со времен заброшенного RailStat) с хорошими результатами. После настройки базовой миграции я обнаружил, что ожидаемое использование очень близко соответствует дизайну MVC Rail. Если вы добавите "импрессиониста" в контроллер, он будет искать модель при регистрации представления страницы в базе данных. Вы можете изменить это поведение или просто вызвать импрессиониста самостоятельно в своем контроллере (или где-нибудь еще), если вы похожи на меня и случайно тестировали его на контроллере, у которого нет модели.

В любом случае, я начал работать с Devise для отслеживания успешных входов в систему, переопределив Devise::SessionsController и просто вызвав импрессионистский метод для @current_member: (не забудьте проверить, не равен ли он! При неудачной регистрации)

class TestSessionController < Devise::SessionsController
  def create
    if not @current_member.nil?
      impressionist(@current_member)
    end
    super
  end
end

Добавление его к другим частям сайта позже для некоторой ограниченной аналитики легко. Единственное, что мне нужно было сделать, это обновить мои маршруты, чтобы использовать новый TestSessionController для маршрута входа в Devise:

post 'login' => 'test_session#create', :as => :member_session

Devise работает, как обычно, без необходимости вносить изменения в Devise, и моя таблица БД импрессионистов индексируется и регистрирует логины. Мне просто понадобится задание на грабли позже, чтобы урезать его еженедельно или около того.

Теперь мне просто нужно разобраться, как составлять график ежедневных входов в систему без необходимости писать кучу зацикленных, грязных запросов...

Если у вас есть модуль:trackable, я нашел это самым простым способом. В модели User (или любой другой модели, которую вы аутентифицируете)

  def update_tracked_fields!(request)
    old_signin = self.last_sign_in_at
    super
    if self.last_sign_in_at != old_signin
      Audit.create :user => self, :action => "login", :ip => self.last_sign_in_ip
    end
  end

(Вдохновлено https://github.com/plataformatec/devise/wiki/How-To:-Turn-off-trackable-for-admin-users)

Есть хороший способ сделать это через Devise.

Warden устанавливает хук с именем after_set_user, который запускается после настройки пользователя. Итак, если у вас есть модель Login, содержащая поле ip, поле logged_in_at и поле user_id, вы можете создать запись только с помощью этих полей.

Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
  Login.create!(:ip => warden.request.ip, :logged_in_at => Time.now, :user_id => record.id)
end

Основываясь на ответе @user208769, ядро Devise::Models::Trackable#update_tracked_fields! метод теперь вызывает вспомогательный метод с именем update_tracked_fields до сохранения. Это означает, что вы можете использовать ActiveRecord::Dirty помощники, чтобы сделать это немного проще:

def update_tracked_fields(request)
  super

  if last_sign_in_at_changed?
    Audit.create(user: self, action: 'login', ip: last_sign_in_ip)
  end
end

Это может быть упрощено еще больше (и будет более надежным с учетом проверок), если audits это отношения по вашей модели:

def update_tracked_fields(request)
  super
  audits.build(action: 'login', ip: last_sign_in_ip) if last_sign_in_at_changed?
end

Devise поддерживает отслеживание последней зарегистрированной даты и последнего зарегистрированного IP-адреса с его помощью. :trackable модуль. Добавив этот модуль в вашу модель пользователя, а затем добавив в базу данных правильные поля, которые:

:sign_in_count,      :type => Integer, :default => 0
:current_sign_in_at, :type => Time
:last_sign_in_at,    :type => Time
:current_sign_in_ip, :type => String
:last_sign_in_ip,    :type => String

Затем вы можете переопределить Devise::SessionsController И его create действие, чтобы затем сохранить :last_sign_in_at а также :last_sign_in_ip на отдельную таблицу в before_create Перезвоните. Затем вы сможете хранить их так долго, как захотите.

Вот пример (scribd_analytics)

create_table 'page_views' do |t|
  t.column 'user_id', :integer 
  t.column 'request_url', :string, :limit => 200
  t.column 'session', :string, :limit => 32
  t.column 'ip_address', :string, :limit => 16
  t.column 'referer', :string, :limit => 200
  t.column 'user_agent', :string, :limit => 200
  t.column 'created_at', :timestamp
end

Добавить целую кучу индексов, в зависимости от запросов

Создать PageView на каждый запрос

Мы использовали ручной SQL-запрос, чтобы снять накладные расходы ActiveRecord на этом

Можно попробовать вставку MySQL с задержкой

Аналитические запросы, как правило, написаны вручную

Используйте "объяснение выбора", чтобы убедиться, что MySQL использует ожидаемые вами индексы

Весы довольно хорошо

НО аналитические запросы дорого обходятся, могут забить основной сервер БД

Наше решение:

use two DB servers in a master/slave setup

move all the analytics queries to the slave

http://www.scribd.com/doc/49575/Scaling-Rails-Presentation-From-Scribd-Launch


Другой вариант проверить это Gattica с Google Analytics

Также есть гем 'paper_trail', который позволяет отслеживать изменения модели.

Другие вопросы по тегам