llconsolidate/lastlogin_consolidate.go

178 lines
3.6 KiB
Go
Raw Normal View History

// lastlogin_consolidate
package main
import (
"flag"
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
"os"
"path"
"path/filepath"
"time"
)
const (
_VERSION = "v0.1"
_tformat = "2006-01-02"
)
var (
opts = Options{
MongoUri: "mongodb://10.39.81.85:27018",
LogFile: "log/llmongo.log",
StartDate: time.Now().Add(-24 * time.Hour).Format(_tformat),
}
)
type Options struct {
MongoUri string
mdb *mgo.Session
ll *mgo.Collection
lc *mgo.Collection
StartDate string
LogFile string
Version bool
}
type LastLogin struct {
User string `json: "user"`
Protocol string `json: "protocol"`
IP string `json: "ip"`
Date time.Time `json: "date"`
ID string `json: "_id"`
}
type LastloginDay struct {
User string `json:"user"`
Date time.Time `json:"date"`
Protocols Protocols `json:"protocols"`
IPs []IPs `json:"ips"`
}
type IPs struct {
IP string `json:"ip"`
Date time.Time `json:"date"`
}
type Protocols struct {
Pop int `json:"pop"`
Imap int `json:"imap"`
Web int `json:"web"`
}
type Index struct {
User string `json:"user"`
Date time.Time `json:"date"`
}
func usage() {
fmt.Println("Usage: llmongo -m <mongo uri> -l <logfile> -d <date> -v\n")
os.Exit(0)
}
func init() {
current, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatal(err)
}
opts.LogFile = path.Join(current, opts.LogFile)
flag.StringVar(&opts.MongoUri, "m", opts.MongoUri, "Mongodb")
flag.StringVar(&opts.LogFile, "l", opts.LogFile, "Logs filename")
flag.StringVar(&opts.StartDate, "d", opts.StartDate, "Date")
flag.BoolVar(&opts.Version, "v", false, "Version")
}
func connectMongo() {
var err error
opts.mdb, err = mgo.Dial(opts.MongoUri)
if err != nil {
log.Println("Mongodb connect Error: ", err.Error())
os.Exit(-3)
}
opts.ll = opts.mdb.DB("dovecot").C("lastlogin")
opts.lc = opts.mdb.DB("dovecot").C("lastlogin_day")
}
func main() {
flag.Usage = usage
flag.Parse()
if opts.Version {
fmt.Println(os.Args[0], _VERSION)
os.Exit(0)
}
fs, err := os.OpenFile(opts.LogFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
fmt.Println("Log file error: ", err.Error())
os.Exit(-4)
}
log.SetOutput(fs)
// log.SetPrefix("[llmongo] ")
start := time.Now()
fmt.Printf("Start: %+v\n", opts)
log.Printf("Start: %+v\n", opts)
connectMongo()
defer opts.mdb.Close()
y, err := time.Parse(_tformat, opts.StartDate)
if err != nil {
fmt.Println("Date Error: ", err)
os.Exit(-1)
}
fmt.Println(y)
ys := time.Date(y.Year(), y.Month(), y.Day(), 0, 0, 0, 0, time.UTC)
ye := time.Date(y.Year(), y.Month(), y.Day(), 23, 59, 59, 0, time.UTC)
fmt.Println(ys, ye)
q := opts.ll.Find(bson.M{"date": bson.M{"$gte": ys, "$lte": ye}}).Sort("user")
ar := []string{}
q.Distinct("user", &ar)
for u := range ar {
ll := LastloginDay{}
ll.User = ar[u]
ll.Date = ys
fmt.Println(ar[u])
nq := opts.ll.Find(bson.M{"date": bson.M{"$gte": ys, "$lte": ye}, "user": ar[u]})
iter := nq.Iter()
result := LastLogin{}
ips := []IPs{}
for iter.Next(&result) {
fmt.Printf("Ip: %s - %s\n", result.IP, result.Date)
ips = append(ips, IPs{IP: result.IP, Date: result.Date})
switch result.Protocol {
case "pop3", "pop":
ll.Protocols.Pop += 1
case "imap":
ll.Protocols.Imap += 1
case "web":
ll.Protocols.Web += 1
}
}
if err := iter.Close(); err != nil {
fmt.Println("Iter: ", err)
}
ll.IPs = ips
fmt.Printf("%+v\n", ll)
_, err := opts.lc.Upsert(Index{User: ll.User, Date: ll.Date}, ll)
if err != nil {
fmt.Println("Insert error: ", err)
}
}
fmt.Println("Stop: ", time.Since(start))
}