Files
go-common/app/service/main/passport/dao/hbase_login_log.go
2019-04-22 18:49:16 +08:00

138 lines
3.5 KiB
Go

package dao
import (
"bytes"
"context"
"encoding/binary"
"io"
"strconv"
"time"
"go-common/app/service/main/passport/model"
"go-common/library/log"
"github.com/tsuna/gohbase/hrpc"
)
const (
_tLoginLog = "ugc:AsoLoginLog"
_fLoginLogInfo = "f"
_cLoginLogMid = "mid"
_cLoginLogTs = "ts"
_cLoginLogLoginIP = "ip"
_cLoginLogType = "t"
_cLoginLogServer = "s"
)
var (
_tLoginLogB = []byte(_tLoginLog)
_fLoginLogInfoB = []byte(_fLoginLogInfo)
_cLoginLogMidB = []byte(_cLoginLogMid)
_cLoginLogTsB = []byte(_cLoginLogTs)
_cLoginLogLoginIPB = []byte(_cLoginLogLoginIP)
_cLoginLogTypeB = []byte(_cLoginLogType)
_cLoginLogServerB = []byte(_cLoginLogServer)
)
// LoginLogs get last limit login logs.
func (d *Dao) LoginLogs(c context.Context, mid int64, limit int) (res []*model.LoginLog, err error) {
ctx, cancel := context.WithTimeout(c, time.Duration(d.c.HBase.LoginLog.ReadTimeout))
defer cancel()
st := rowKeyLoginLog(mid, _int64Max)
ed := rowKeyLoginLog(mid, 0)
var scaner hrpc.Scanner
scaner, err = d.loginLogHBase.ScanRange(ctx, _tLoginLogB, st, ed)
if err != nil {
log.Error("hbase.ScanRange(%s, %s, %s) error(%v)", _tLoginLogB, st, ed, err)
return
}
res = make([]*model.LoginLog, 0)
for ; limit > 0; limit-- {
var u *model.LoginLog
var r *hrpc.Result
r, err = scaner.Next()
if err != nil {
if err == io.EOF {
err = nil
break
}
return
}
if u, err = scanLoginLog(r.Cells); err != nil {
scaner.Close()
return
}
if u != nil {
res = append(res, u)
}
}
if err := scaner.Close(); err != nil {
log.Error("hbase.Scanner.Close error(%v)", err)
}
return
}
// rowKeyLoginLog generate row key of login log.
func rowKeyLoginLog(mid, ts int64) (res []byte) {
buf := bytes.Buffer{}
b := make([]byte, 8)
// reverse mid bytes
binary.BigEndian.PutUint64(b, uint64(mid))
reverse(b)
buf.Write(b)
// (int64_max - ts) bytes
binary.BigEndian.PutUint64(b, uint64(_int64Max-ts))
buf.Write(b)
res = buf.Bytes()
return
}
func reverse(b []byte) {
l := len(b)
for i := 0; i < l/2; i++ {
t := b[i]
b[i] = b[l-1-i]
b[l-1-i] = t
}
}
func scanLoginLog(cells []*hrpc.Cell) (res *model.LoginLog, err error) {
if len(cells) == 0 {
return
}
res = new(model.LoginLog)
for _, cell := range cells {
if bytes.Equal(cell.Family, _fLoginLogInfoB) {
switch {
case bytes.Equal(cell.Qualifier, _cLoginLogMidB):
if res.Mid, err = strconv.ParseInt(string(cell.Value), 10, 64); err != nil {
log.Error("failed to parse mid from cell, strconv.ParseInt(%s, 10, 64) error(%v)", cell.Value, err)
return
}
case bytes.Equal(cell.Qualifier, _cLoginLogTsB):
if res.Timestamp, err = strconv.ParseInt(string(cell.Value), 10, 64); err != nil {
log.Error("failed to parse timestamp from cell, strconv.ParseInt(%s, 10, 64) error(%v)", cell.Value, err)
return
}
case bytes.Equal(cell.Qualifier, _cLoginLogLoginIPB):
if res.LoginIP, err = strconv.ParseInt(string(cell.Value), 10, 64); err != nil {
log.Error("failed to parse loginip from cell, strconv.ParseInt(%s, 10, 64) error(%v)", cell.Value, err)
return
}
case bytes.Equal(cell.Qualifier, _cLoginLogTypeB):
if res.Type, err = strconv.ParseInt(string(cell.Value), 10, 64); err != nil {
log.Error("failed to parse type from cell, strconv.ParseInt(%s, 10, 64) error(%v)", cell.Value, err)
return
}
case bytes.Equal(cell.Qualifier, _cLoginLogServerB):
res.Server = string(cell.Value)
}
}
}
return
}