func (l *ChatLogs) HandleEvict(key interface{}, chatLog interface{}) {
	chatLog.(*ChatLog).Close()
}
HandleEvict close evicted logs
package main
import (
	"log"
	"os"
	"path/filepath"
	"sync"
	"time"
	"github.com/hashicorp/golang-lru"
	"github.com/MemeLabs/overrustlelogs/common"
)
type ChatLog struct {
	sync.Mutex
	f        *os.File
	nicks    common.NickList
	modified time.Time
}
func NewChatLog(path string) (*ChatLog, error) {
	dir := filepath.Dir(path)
	if _, err := os.Stat(dir); err != nil {
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return nil, err
		}
	}
	if _, err := common.UncompressFile(path); !os.IsNotExist(err) && err != nil {
		log.Printf("error reading log %s %s", path, err)
	}
	f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return nil, err
	}
	nicks := common.NickList{}
	common.ReadNickList(nicks, nickPath(path))
	return &ChatLog{
		f:        f,
		nicks:    nicks,
		modified: time.Now(),
	}, nil
}
func (l *ChatLog) WriteNicks() {
	l.Lock()
	if err := l.nicks.WriteTo(nickPath(l.f.Name())); err != nil {
		log.Printf("error writing nicks for %s %s", l.f.Name(), err)
	}
	l.Unlock()
}
func (l *ChatLog) Close() {
	l.WriteNicks()
	l.Lock()
	l.f.Close()
	if _, err := common.CompressFile(l.f.Name()); !os.IsNotExist(err) && err != nil {
		log.Printf("error compressing log %s %s", l.f.Name(), err)
	}
	l.Unlock()
}
func (l *ChatLog) Write(timestamp time.Time, nick string, message string) {
	l.Lock()
	l.nicks.Add(nick)
	l.f.WriteString(timestamp.Format("[2006-01-02 15:04:05 MST] ") + nick + ": " + message + "\n")
	l.modified = time.Now()
	l.Unlock()
}
func (l *ChatLog) Modified() time.Time {
	l.Lock()
	defer l.Unlock()
	return l.modified
}
func nickPath(path string) string {
	ext := filepath.Ext(path)
	return path[:len(path)-len(ext)] + ".nicks"
}
type ChatLogs struct {
	logs *lru.Cache
}
func NewChatLogs() *ChatLogs {
	l := &ChatLogs{}
	cache, err := lru.NewWithEvict(common.GetConfig().MaxOpenLogs/2, l.HandleEvict)
	if err != nil {
		log.Fatalf("error creating log cache %s", err)
	}
	l.logs = cache
	go l.housekeeping()
	return l
}
func (l *ChatLogs) housekeeping() {
	const interval = 2 * time.Minute
	tick := time.NewTicker(interval)
	for now := range tick.C {
		for _, k := range l.logs.Keys() {
			if v, ok := l.logs.Peek(k); ok {
				c := v.(*ChatLog)
				idle := now.Sub(c.Modified())
				if idle > time.Hour {
					l.logs.Remove(k)
					c.Close()
				} else if idle < interval {
					c.WriteNicks()
				}
			}
		}
	}
}