谁在那里? - 跟踪网站访问量

时间:2015-07-26 00:07:54

标签: postgresql activerecord logging sinatra

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

我对访问的定义:

  

当某人或某物(机器人)访问您的网站时,就会发生访问。它由一个或多个页面浏览/点击组成。一位访问者可以多次访问您的网站。

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

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

  1. 访客IP地址
  2. 时间访问开始(页面已打开)
  3. 时间访问结束(页面已关闭)
  4. 此网站不经常查看,因此我想在使用activerecord访问的postgres数据库中记录每次访问。 日志记录的工作方式是:

    1. 用户访问页面
    2. 会话已启动,ipmac_addresstimeview_id已登录Visit
    3. 查看的每个页面都记录在PageView
    4. 用户关闭页面
    5. 会话已清除,timeview_id已登录Visit
    6. 数据库格式

      • 访问次数(表)
        • ip(Column,string)
        • mac_address(Column,string)
        • view_id(Column,int)
        • 时间(列,日期时间)
      • PageViews(表格)
        • 页面(列,字符串)
        • 时间(列,日期时间)
        • view_id(Column,int)

      示例迁移文件:

      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
      

1 个答案:

答案 0 :(得分:1)

  

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

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

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

HTTP是一种无状态协议,这意味着#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,这应该是直截了当的。

注意,我基本上把这个代码从我的背后拉出来,所以考虑任何或所有可能会破坏并且不稳定,但是这样你就可以得到这个想法。就像我上面提到的,我可能会削减大部分内容并使用日志和一些明智的正则表达式。