|  | @@ -0,0 +1,77 @@
 | 
											
												
													
														|  | 
 |  | +package log
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +import (
 | 
											
												
													
														|  | 
 |  | +	"log"
 | 
											
												
													
														|  | 
 |  | +	"os"
 | 
											
												
													
														|  | 
 |  | +)
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type AccessStatus string
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const (
 | 
											
												
													
														|  | 
 |  | +	AccessAccepted = AccessStatus("accepted")
 | 
											
												
													
														|  | 
 |  | +	AccessRejected = AccessStatus("rejected")
 | 
											
												
													
														|  | 
 |  | +)
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type accessLogger interface {
 | 
											
												
													
														|  | 
 |  | +	Log(from, to string, status AccessStatus, reason string)
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type noOpAccessLogger struct {
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (logger *noOpAccessLogger) Log(from, to string, status AccessStatus, reason string) {
 | 
											
												
													
														|  | 
 |  | +	// Swallow
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type accessLog struct {
 | 
											
												
													
														|  | 
 |  | +	From   string
 | 
											
												
													
														|  | 
 |  | +	To     string
 | 
											
												
													
														|  | 
 |  | +	Status AccessStatus
 | 
											
												
													
														|  | 
 |  | +	Reason string
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +type fileAccessLogger struct {
 | 
											
												
													
														|  | 
 |  | +	queue  chan *accessLog
 | 
											
												
													
														|  | 
 |  | +	logger *log.Logger
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (logger *fileAccessLogger) Log(from, to string, status AccessStatus, reason string) {
 | 
											
												
													
														|  | 
 |  | +	logger.queue <- &accessLog{
 | 
											
												
													
														|  | 
 |  | +		From:   from,
 | 
											
												
													
														|  | 
 |  | +		To:     to,
 | 
											
												
													
														|  | 
 |  | +		Status: status,
 | 
											
												
													
														|  | 
 |  | +		Reason: reason,
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (logger *fileAccessLogger) Run() {
 | 
											
												
													
														|  | 
 |  | +	for entry := range logger.queue {
 | 
											
												
													
														|  | 
 |  | +		logger.logger.Println(entry.From + " " + string(entry.Status) + " " + entry.To + " " + entry.Reason)
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func newFileAccessLogger(path string) accessLogger {
 | 
											
												
													
														|  | 
 |  | +	file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
 | 
											
												
													
														|  | 
 |  | +	if err != nil {
 | 
											
												
													
														|  | 
 |  | +		log.Printf("Unable to create or open file (%s): %v\n", path, err)
 | 
											
												
													
														|  | 
 |  | +		return nil
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	return &fileAccessLogger{
 | 
											
												
													
														|  | 
 |  | +		queue:  make(chan *accessLog, 16),
 | 
											
												
													
														|  | 
 |  | +		logger: log.New(file, "", log.Ldate|log.Ltime),
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +var accessLoggerInstance accessLogger = &noOpAccessLogger{}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func InitAccessLogger(file string) {
 | 
											
												
													
														|  | 
 |  | +	logger := newFileAccessLogger(file)
 | 
											
												
													
														|  | 
 |  | +	if logger != nil {
 | 
											
												
													
														|  | 
 |  | +		go logger.(*fileAccessLogger).Run()
 | 
											
												
													
														|  | 
 |  | +		accessLoggerInstance = logger
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func Access(from, to string, status AccessStatus, reason string) {
 | 
											
												
													
														|  | 
 |  | +	accessLoggerInstance.Log(from, to, status, reason)
 | 
											
												
													
														|  | 
 |  | +}
 |