38ec946cba 2014-07-03 1: -- module counter - counts some junk
38ec946cba 2014-07-03 2:
b33171b487 2018-06-01 3: local _counter = {}
b33171b487 2018-06-01 4:
b33171b487 2018-06-01 5: local redis = require 'resty.redis'
b33171b487 2018-06-01 6: local cjson = require 'cjson'
b33171b487 2018-06-01 7:
b33171b487 2018-06-01 8: local closed = false
b33171b487 2018-06-01 9:
b33171b487 2018-06-01 10: function _counter.exit()
b33171b487 2018-06-01 11: if not closed then
b33171b487 2018-06-01 12: local ok, err = _counter.red:set_keepalive(60000, 10)
b33171b487 2018-06-01 13: if not ok then
b33171b487 2018-06-01 14: ngx.log(ngx.ERR, "redis keepalive: " .. err)
b33171b487 2018-06-01 15: end
b33171b487 2018-06-01 16: closed = true
b33171b487 2018-06-01 17: end
b33171b487 2018-06-01 18: end
b33171b487 2018-06-01 19:
b33171b487 2018-06-01 20: function _counter.decode_bulk(reply)
b33171b487 2018-06-01 21: -- decodes values from array into dict
38ec946cba 2014-07-03 22: local data = {}
38ec946cba 2014-07-03 23: for j=1, #reply, 2 do
38ec946cba 2014-07-03 24: data[reply[j] ] = reply[j+1]
38ec946cba 2014-07-03 25: end
b33171b487 2018-06-01 26: return data
b33171b487 2018-06-01 27: end
b33171b487 2018-06-01 28:
b33171b487 2018-06-01 29: function _counter.connect()
b33171b487 2018-06-01 30: -- connect to redis
b33171b487 2018-06-01 31: _counter.red = redis:new()
b33171b487 2018-06-01 32: local ok, err = _counter.red:connect('127.0.0.1', 6379)
b33171b487 2018-06-01 33: if not ok then
b33171b487 2018-06-01 34: ngx.log(ngx.ERR, 'redis connection failed: ', err)
b33171b487 2018-06-01 35: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 36: end
b33171b487 2018-06-01 37: closed = false
b33171b487 2018-06-01 38: end
b33171b487 2018-06-01 39:
b33171b487 2018-06-01 40: function _counter.check_schema()
b33171b487 2018-06-01 41: if ngx.var.site_schema == nil then
b33171b487 2018-06-01 42: ngx.log(ngx.ERR, "No 'site_schema' specified");
b33171b487 2018-06-01 43: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 44: end
b33171b487 2018-06-01 45: end
b33171b487 2018-06-01 46:
b33171b487 2018-06-01 47: function _counter.update()
b33171b487 2018-06-01 48: _counter.check_schema()
b33171b487 2018-06-01 49: local today = os.date('*t')
b33171b487 2018-06-01 50: local timestamp = os.time{year = today['year'], month = today['month'], day = today['day']}
b33171b487 2018-06-01 51: local referer = '-';
b33171b487 2018-06-01 52:
b33171b487 2018-06-01 53: if ngx.var.http_referer ~= nil then
b33171b487 2018-06-01 54: _, _, referer = string.find(ngx.var.http_referer, '^https?://([^?&]+)')
b33171b487 2018-06-01 55: --ngx.log(ngx.ERR, "Referer: " .. referer)
b33171b487 2018-06-01 56: end
b33171b487 2018-06-01 57:
b33171b487 2018-06-01 58: local key = ngx.var.site_schema .. '_counter_' .. timestamp .. '_' .. referer
b33171b487 2018-06-01 59: -- ngx.log(ngx.ERR, "Using key: " .. key)
b33171b487 2018-06-01 60:
b33171b487 2018-06-01 61: local res, err
b33171b487 2018-06-01 62: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 63: _counter.red:multi()
b33171b487 2018-06-01 64: _counter.red:hincrby(key, 'today', 1)
b33171b487 2018-06-01 65: _counter.red:hgetall(key)
b33171b487 2018-06-01 66: _counter.red:exec()
b33171b487 2018-06-01 67: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 68: if not res then
b33171b487 2018-06-01 69: ngx.log(ngx.ERR, 'redis pipeline failed: ', err)
b33171b487 2018-06-01 70: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 71: end
b33171b487 2018-06-01 72:
b33171b487 2018-06-01 73: local data = _counter.red:array_to_hash(res[4][2])
b33171b487 2018-06-01 74: -- ngx.log(ngx.ERR, "Got data: " .. cjson.encode(data))
b33171b487 2018-06-01 75:
b33171b487 2018-06-01 76: if tonumber(data.today) == 1 then
b33171b487 2018-06-01 77: ngx.log(ngx.ERR, "Reading postgres")
b33171b487 2018-06-01 78: -- postgres fallback
b33171b487 2018-06-01 79: result = ngx.location.capture('/postgres', {
b33171b487 2018-06-01 80: method = ngx.HTTP_PUT,
b33171b487 2018-06-01 81: body = "select * from " .. ngx.var.site_schema .. ".get_stats('" .. referer .. "') as (today int, lastday int, week bigint, whole bigint);"
b33171b487 2018-06-01 82: })
b33171b487 2018-06-01 83: if result.status ~= 200 or not result.body then
b33171b487 2018-06-01 84: ngx.log(ngx.ERR, 'postgres access failed')
b33171b487 2018-06-01 85: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 86: else
b33171b487 2018-06-01 87: local unrds = require "rds.parser"
b33171b487 2018-06-01 88: local res, err = unrds.parse(result.body)
b33171b487 2018-06-01 89:
b33171b487 2018-06-01 90: if res == nil then
b33171b487 2018-06-01 91: ngx.log(ngx.ERR, 'failed to obtain data: ' .. err)
b33171b487 2018-06-01 92: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 93: else
b33171b487 2018-06-01 94: data = res.resultset[1]
b33171b487 2018-06-01 95: data.today = data.today + 1
b33171b487 2018-06-01 96: ngx.log(ngx.ERR, "Got data: " .. cjson.encode(data))
b33171b487 2018-06-01 97:
b33171b487 2018-06-01 98: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 99: _counter.red:multi()
b33171b487 2018-06-01 100: _counter.red:hmset(key, data)
b33171b487 2018-06-01 101: _counter.red:expire(key, 129600)
b33171b487 2018-06-01 102: _counter.red:exec()
b33171b487 2018-06-01 103: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 104: if not res then
b33171b487 2018-06-01 105: ngx.log(ngx.ERR, 'redis pipeline failed: ', err)
b33171b487 2018-06-01 106: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 107: end
b33171b487 2018-06-01 108: end
b33171b487 2018-06-01 109: end
b33171b487 2018-06-01 110: end
b33171b487 2018-06-01 111:
b33171b487 2018-06-01 112: ngx.say(cjson.encode(data))
b33171b487 2018-06-01 113: ngx.eof()
b33171b487 2018-06-01 114:
b33171b487 2018-06-01 115: local uid = ''
b33171b487 2018-06-01 116:
b33171b487 2018-06-01 117: if ngx.var.uid_got ~= nil and string.find(ngx.var.uid_got, 'uid=') == 1 then
b33171b487 2018-06-01 118: uid = string.sub(ngx.var.uid_got, 5)
b33171b487 2018-06-01 119: elseif ngx.var.uid_set ~= nil and string.find(ngx.var.uid_set, 'uid=') == 1 then
b33171b487 2018-06-01 120: uid = string.sub(ngx.var.uid_set, 5)
b33171b487 2018-06-01 121: end
b33171b487 2018-06-01 122:
b33171b487 2018-06-01 123: local hit_key = uid .. '_' .. referer .. '_' .. ngx.var.remote_addr
b33171b487 2018-06-01 124: local key_pending = ngx.var.site_schema .. '_counter_pending'
b33171b487 2018-06-01 125:
b33171b487 2018-06-01 126: _counter.red:init_pipeline(4)
b33171b487 2018-06-01 127: _counter.red:multi()
b33171b487 2018-06-01 128: _counter.red:hincrby(key_pending, hit_key, 1)
b33171b487 2018-06-01 129: _counter.red:expire(key_pending, 604800)
b33171b487 2018-06-01 130: _counter.red:exec()
b33171b487 2018-06-01 131: res, err = _counter.red:commit_pipeline()
b33171b487 2018-06-01 132: if not res then
b33171b487 2018-06-01 133: ngx.log(ngx.ERR, 'redis transaction failed: ', err)
b33171b487 2018-06-01 134: ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
b33171b487 2018-06-01 135: end
b33171b487 2018-06-01 136: end
b33171b487 2018-06-01 137:
b33171b487 2018-06-01 138: return _counter