postgresql - 谁在那儿? - 跟踪网站访问

标签 postgresql activerecord logging sinatra

我正在用 sinatra 和 heroku 编写一个网站,我想找到一种方法来跟踪对我网站的每次访问。我看过实际的分析程序(例如 google analytics )并选择不使用它们,因为我想自己学习如何做。

我对访问的定义:

A visit happens when someone or something (robot) visits your site. It consists of one or more page views/ hits. One visitor can make multiple visits to your site.

来源:http://www.opentracker.net/article/hits-or-pageviews

对于每次访问,我想跟踪:

  1. 访客IP地址
  2. 访问开始时间(页面打开)
  3. 时间访问结束(页面关闭)

这个网站不常被浏览,所以我想将每次访问记录在一个使用 activerecord 访问的 postgres 数据库中。 日志记录的工作方式是这样的:

  1. 用户访问页面
  2. session 开始,ipmac_addresstimeview_id登录访问
  3. 查看的每个页面都记录在 PageView
  4. 用户关闭页面
  5. Session被清除,timeview_id被登录到Visit

数据库格式

  • 访问次数(表格)
    • ip(列,字符串)
    • mac_address(列,字符串)
    • view_id(列,整数)
    • 时间(列,日期时间)
  • 页面浏览量(表格)
    • 页面(列,字符串)
    • 时间(列,日期时间)
    • view_id(列,整数)

示例迁移文件:

class Main < ActiveRecord::Migration
  def change
    create_table :visits do |item|
        item.string :ip
        item.string :mac_address
        item.datetime :time
        item.int :visit_id
    end
    create_table :pageviews do |item|
        item.int :visit_id
        item.string :page
        item.datetime :time
  end
end

最佳答案

For each visit, I would like to track:

  1. Visitor IP address
  2. Time visit began (page was opened)
  3. Time visit ended (page was closed)

您之前在列表中也有 MAC 地址,但重申一下 - 它们不用于路由 Internet,仅用于本地网络,因此保存该信息几乎毫无意义,即使您可以获取它。

HTTP 是一种无状态协议(protocol),这意味着 #3 无法通过 HTTP 方法实现,但可以通过 javascript 实现。可能最简单的方法是以可接受的时间间隔进行轮询,更新时间。

#1 和#2 已经被您的基本服务器日志捕获,我会使用它们 - 为什么要重复工作? - 但我将添加如何使用 Sinatra 通过模型来完成此操作。

如果您使用before 过滤器,您可以轻松捕获#1 和#2。 Request object有一些你想要的东西,你需要时间,并确保它是该 ip 的唯一用户:

before do
  # this is pseudo code, Sequel style, you can work this bit out
  # for ActiveRecord
  user =
    if user_id = session[:user]
      User[user_id]
    else
      User.create
    end

  # you may want to check if there's an existing session for this page
  # as refreshes would run this again. It's up to you.
  user.add_visit Visit.create(page: request.path,ip: request.ip, start: Time.now.rfc2822])
  session[:analytics] = visit.id
  session[:user] = user.session_id # *don't* just bung the
                                   # user id in there
end

你需要一个路由来记录结束时间

patch "/analytics", :provides => :json do
  visit_id = session[:analytics]
  user = User[ :session_id => session[:user] ]
  visit = user.visits.find(:id => visit_id)
  visit.end = Rack::Utils.rfc2822(params[:end])
  visit.save
  halt 204 # take your pick of success numbers
           # you should also check for errors
           # and check the input is valid
           # and you may want to return some JSON to the
           # calling javascript.
  # Also think about how to restrict access to this
  # route to only authorised callers. Since you're providing the
  # javascript, you can place variables in them by generating
  # parts on the fly and serving it via a Sinatra route etc.
end

我不打算编写 javascript,那应该很简单。

请注意,我基本上是从我的背后提取这段代码,所以请考虑其中任何一个或所有可能会破坏和不稳定的代码,但它是为了让您明白。就像我上面提到的,我可能会削减大部分内容并使用日志和一些明智的正则表达式。

关于postgresql - 谁在那儿? - 跟踪网站访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31632295/

相关文章:

postgresql - postgis 不适用于所有 postgres 用户

java - PostgreSQL getSequence 当前值并传递给 id

apache - (Apache) 错误日志美化器

c# - Asp.net 核心 - 调用方法()不调用中间件

javascript - winston Elasticsearch : TypeError: Elasticsearch is not a constructor

postgresql - 如何在 PostgreSQL 中为基于 Web 的应用程序设置用户帐户

ruby-on-rails - 使用 JSON 和 POST 将我的 iOS 应用程序连接到 Web 应用程序问题

ruby-on-rails - :autosave property of has_many associations broken in Rails 2. 3.4?

ruby-on-rails - ActiveRecord update_attributes 忽略无效键

sql - 如何按rails中关联的created_at列排序?