38ec946cba 2014-07-03 arcade@b1t.na: -- module counter - counts some junk
38ec946cba 2014-07-03 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local _counter = {}
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local redis = require 'resty.redis'
b33171b487 2018-06-01 arcade@b1t.na: local cjson = require 'cjson'
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local closed = false
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: function _counter.exit()
b33171b487 2018-06-01 arcade@b1t.na: if not closed then
b33171b487 2018-06-01 arcade@b1t.na: local ok, err = _counter.red:set_keepalive(60000, 10)
b33171b487 2018-06-01 arcade@b1t.na: if not ok then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, "redis keepalive: " .. err)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: closed = true
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: function _counter.decode_bulk(reply)
b33171b487 2018-06-01 arcade@b1t.na: -- decodes values from array into dict
38ec946cba 2014-07-03 arcade@b1t.na: local data = {}
38ec946cba 2014-07-03 arcade@b1t.na: for j=1, #reply, 2 do
38ec946cba 2014-07-03 arcade@b1t.na: data[reply[j] ] = reply[j+1]
38ec946cba 2014-07-03 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: return data
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: function _counter.connect()
b33171b487 2018-06-01 arcade@b1t.na: -- connect to redis
b33171b487 2018-06-01 arcade@b1t.na: _counter.red = redis:new()
b33171b487 2018-06-01 arcade@b1t.na: local ok, err = _counter.red:connect('127.0.0.1', 6379)
b33171b487 2018-06-01 arcade@b1t.na: if not ok then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'redis connection failed: ', err)
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: closed = false
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: function _counter.check_schema()
b33171b487 2018-06-01 arcade@b1t.na: if ngx.var.site_schema == nil then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, "No 'site_schema' specified");
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: function _counter.update()
b33171b487 2018-06-01 arcade@b1t.na: _counter.check_schema()
b33171b487 2018-06-01 arcade@b1t.na: local today = os.date('*t')
b33171b487 2018-06-01 arcade@b1t.na: local timestamp = os.time{year = today['year'], month = today['month'], day = today['day']}
b33171b487 2018-06-01 arcade@b1t.na: local referer = '-';
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: if ngx.var.http_referer ~= nil then
b33171b487 2018-06-01 arcade@b1t.na: _, _, referer = string.find(ngx.var.http_referer, '^https?://([^?&]+)')
b33171b487 2018-06-01 arcade@b1t.na: --ngx.log(ngx.ERR, "Referer: " .. referer)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local key = ngx.var.site_schema .. '_counter_' .. timestamp .. '_' .. referer
b33171b487 2018-06-01 arcade@b1t.na: -- ngx.log(ngx.ERR, "Using key: " .. key)
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local res, err
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:multi()
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:hincrby(key, 'today', 1)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:hgetall(key)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:exec()
b33171b487 2018-06-01 arcade@b1t.na: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 arcade@b1t.na: if not res then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'redis pipeline failed: ', err)
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local data = _counter.red:array_to_hash(res[4][2])
b33171b487 2018-06-01 arcade@b1t.na: -- ngx.log(ngx.ERR, "Got data: " .. cjson.encode(data))
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: if tonumber(data.today) == 1 then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, "Reading postgres")
b33171b487 2018-06-01 arcade@b1t.na: -- postgres fallback
b33171b487 2018-06-01 arcade@b1t.na: result = ngx.location.capture('/postgres', {
b33171b487 2018-06-01 arcade@b1t.na: method = ngx.HTTP_PUT,
b33171b487 2018-06-01 arcade@b1t.na: body = "select * from " .. ngx.var.site_schema .. ".get_stats('" .. referer .. "') as (today int, lastday int, week bigint, whole bigint);"
b33171b487 2018-06-01 arcade@b1t.na: })
b33171b487 2018-06-01 arcade@b1t.na: if result.status ~= 200 or not result.body then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'postgres access failed')
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: else
b33171b487 2018-06-01 arcade@b1t.na: local unrds = require "rds.parser"
b33171b487 2018-06-01 arcade@b1t.na: local res, err = unrds.parse(result.body)
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: if res == nil then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'failed to obtain data: ' .. err)
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: else
b33171b487 2018-06-01 arcade@b1t.na: data = res.resultset[1]
b33171b487 2018-06-01 arcade@b1t.na: data.today = data.today + 1
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, "Got data: " .. cjson.encode(data))
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:multi()
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:hmset(key, data)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:expire(key, 129600)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:exec()
b33171b487 2018-06-01 arcade@b1t.na: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 arcade@b1t.na: if not res then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'redis pipeline failed: ', err)
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: ngx.say(cjson.encode(data))
b33171b487 2018-06-01 arcade@b1t.na: ngx.eof()
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local uid = ''
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: if ngx.var.uid_got ~= nil and string.find(ngx.var.uid_got, 'uid=') == 1 then
b33171b487 2018-06-01 arcade@b1t.na: uid = string.sub(ngx.var.uid_got, 5)
b33171b487 2018-06-01 arcade@b1t.na: elseif ngx.var.uid_set ~= nil and string.find(ngx.var.uid_set, 'uid=') == 1 then
b33171b487 2018-06-01 arcade@b1t.na: uid = string.sub(ngx.var.uid_set, 5)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: local hit_key = uid .. '_' .. referer .. '_' .. ngx.var.remote_addr
b33171b487 2018-06-01 arcade@b1t.na: local key_pending = ngx.var.site_schema .. '_counter_pending'
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:multi()
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:hincrby(key_pending, hit_key, 1)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:expire(key_pending, 604800)
b33171b487 2018-06-01 arcade@b1t.na: _counter.red:exec()
b33171b487 2018-06-01 arcade@b1t.na: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 arcade@b1t.na: if not res then
b33171b487 2018-06-01 arcade@b1t.na: ngx.log(ngx.ERR, 'redis transaction failed: ', err)
b33171b487 2018-06-01 arcade@b1t.na: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na: end
b33171b487 2018-06-01 arcade@b1t.na:
b33171b487 2018-06-01 arcade@b1t.na: return _counter