1
0
Fork 0

Deprecate code.google.com/p/log4go

- Add new internal `rqlite/log` package
- Replace `log4go` with `rqlite/log`
- Adapt log formatting in existing logs

Fixes #21
master
Fernando Álvarez 10 years ago
parent cdc6021ae7
commit eba40187a9

@ -4,7 +4,7 @@ import (
"github.com/goraft/raft"
"github.com/otoolep/rqlite/db"
log "code.google.com/p/log4go"
"github.com/otoolep/rqlite/log"
)
// This command encapsulates a sqlite statement.
@ -26,7 +26,7 @@ func (c *ExecuteCommand) CommandName() string {
// Apply executes an sqlite statement.
func (c *ExecuteCommand) Apply(server raft.Server) (interface{}, error) {
log.Trace("Applying ExecuteCommand: '%s'", c.Stmt)
log.Tracef("Applying ExecuteCommand: '%s'", c.Stmt)
db := server.Context().(*db.DB)
return nil, db.Execute(c.Stmt)
}
@ -53,7 +53,7 @@ func (c *TransactionExecuteCommandSet) CommandName() string {
// Apply executes a set of sqlite statements, within a transaction. All statements
// will take effect, or none.
func (c *TransactionExecuteCommandSet) Apply(server raft.Server) (interface{}, error) {
log.Trace("Applying TransactionExecuteCommandSet of size %d", len(c.Stmts))
log.Tracef("Applying TransactionExecuteCommandSet of size %d", len(c.Stmts))
commitSuccess := false
db := server.Context().(*db.DB)
@ -61,26 +61,26 @@ func (c *TransactionExecuteCommandSet) Apply(server raft.Server) (interface{}, e
if !commitSuccess {
err := db.RollbackTransaction()
if err != nil {
log.Error("Failed to rollback transaction: %s", err.Error)
log.Errorf("Failed to rollback transaction: %s", err.Error())
}
}
}()
err := db.StartTransaction()
if err != nil {
log.Error("Failed to start transaction:", err.Error())
log.Errorf("Failed to start transaction: %s", err.Error())
return nil, err
}
for i := range c.Stmts {
err = db.Execute(c.Stmts[i])
if err != nil {
log.Error("Failed to execute statement within transaction", err.Error())
log.Errorf("Failed to execute statement within transaction: %s", err.Error())
return nil, err
}
}
err = db.CommitTransaction()
if err != nil {
log.Error("Failed to commit transaction:", err.Error())
log.Errorf("Failed to commit transaction: %s", err.Error())
return nil, err
} else {
commitSuccess = true

@ -8,7 +8,7 @@ import (
_ "github.com/mattn/go-sqlite3"
log "code.google.com/p/log4go"
"github.com/otoolep/rqlite/log"
)
const (
@ -26,17 +26,17 @@ type RowResults []map[string]string
// New creates a new database. Deletes any existing database.
func New(dbPath string) *DB {
log.Trace("Removing any existing SQLite database at %s", dbPath)
log.Tracef("Removing any existing SQLite database at %s", dbPath)
os.Remove(dbPath)
return Open(dbPath)
}
// Open an existing database, creating it if it does not exist.
func Open(dbPath string) *DB {
log.Trace("Opening SQLite database path at %s", dbPath)
log.Tracef("Opening SQLite database path at %s", dbPath)
dbc, err := sql.Open("sqlite3", dbPath)
if err != nil {
log.Error(err)
log.Error(err.Error())
return nil
}
return &DB{
@ -53,11 +53,11 @@ func (db *DB) Close() error {
// RowResults.
func (db *DB) Query(query string) (RowResults, error) {
if !strings.HasPrefix(strings.ToUpper(query), "SELECT ") {
log.Warn("Query \"%s\" may modify the database", query)
log.Warnf("Query \"%s\" may modify the database", query)
}
rows, err := db.dbConn.Query(query)
if err != nil {
log.Error("failed to execute SQLite query", err.Error())
log.Errorf("failed to execute SQLite query: %s", err.Error())
return nil, err
}
defer rows.Close()
@ -74,7 +74,7 @@ func (db *DB) Query(query string) (RowResults, error) {
for rows.Next() {
err = rows.Scan(dest...)
if err != nil {
log.Error("failed to scan SQLite row", err.Error())
log.Errorf("failed to scan SQLite row: %s", err.Error())
return nil, err
}
@ -88,7 +88,7 @@ func (db *DB) Query(query string) (RowResults, error) {
}
results = append(results, r)
}
log.Debug(func() string { return "Executed query successfully: " + query })
log.Debugf("Executed query successfully: %s", query)
return results, nil
}
@ -100,7 +100,8 @@ func (db *DB) Execute(stmt string) error {
return fmt.Sprintf("Error executing \"%s\", error: %s", stmt, err.Error())
}
return fmt.Sprintf("Successfully executed \"%s\"", stmt)
})
}())
return err
}
@ -112,7 +113,7 @@ func (db *DB) StartTransaction() error {
return "Error starting transaction"
}
return "Successfully started transaction"
})
}())
return err
}
@ -124,7 +125,7 @@ func (db *DB) CommitTransaction() error {
return "Error ending transaction"
}
return "Successfully ended transaction"
})
}())
return err
}
@ -137,6 +138,6 @@ func (db *DB) RollbackTransaction() error {
return "Error rolling back transaction"
}
return "Successfully rolled back transaction"
})
}())
return err
}

@ -0,0 +1,103 @@
package log
import (
"io"
"log"
)
// Log levels
const (
TRACE = iota // 0
DEBUG = iota // 1
INFO = iota // 2
WARN = iota // 3
ERROR = iota // 4
)
// Level set for logs
var Level = TRACE
// SetLevel sets the log level
// given a string
func SetLevel(level string) {
switch level {
case "TRACE":
Level = TRACE
case "DEBUG":
Level = DEBUG
case "INFO":
Level = INFO
case "WARN":
Level = WARN
case "ERROR":
Level = ERROR
default:
Level = TRACE
}
}
// SetOutput set the output destination
// of logs
func SetOutput(w io.Writer) {
log.SetOutput(w)
}
// Tracef writes a formatted log on TRACE level
func Tracef(format string, v ...interface{}) {
if Level <= TRACE {
log.Printf("[TRACE] "+format, v...)
}
}
// Trace writes a log on TRACE level
func Trace(s string) {
Tracef(s)
}
// Debugf writes a formatted log on DEBUG level
func Debugf(format string, v ...interface{}) {
if Level <= DEBUG {
log.Printf("[DEBUG] "+format, v...)
}
}
// Debug writes a log on DEBUG level
func Debug(s string) {
Debugf(s)
}
// Infof writes a formatted log on INFO level
func Infof(format string, v ...interface{}) {
if Level <= INFO {
log.Printf("[INFO ] "+format, v...)
}
}
// Info write a log on INFO level
func Info(s string) {
Infof(s)
}
// Warnf writes a formatted log on WARN level
func Warnf(format string, v ...interface{}) {
if Level <= WARN {
log.Printf("[WARN ] "+format, v...)
}
}
// Warn write a log on WARN level
func Warn(s string) {
Warnf(s)
}
// Errorf writes a formatted log on ERROR level
func Errorf(format string, v ...interface{}) {
if Level <= ERROR {
log.Printf("[ERROR] "+format, v...)
}
}
// Error write a log on ERROR level
func Error(s string) {
Errorf(s)
}

@ -0,0 +1,131 @@
package log
import (
"bytes"
"io"
"os"
"testing"
. "gopkg.in/check.v1"
)
// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) {
TestingT(t)
}
type LogSuite struct{}
var _ = Suite(&LogSuite{})
func (s *LogSuite) TestSetLevel(c *C) {
SetLevel("DEBUG")
c.Assert(Level, Equals, DEBUG)
SetLevel("INFO")
c.Assert(Level, Equals, INFO)
SetLevel("WARN")
c.Assert(Level, Equals, WARN)
SetLevel("ERROR")
c.Assert(Level, Equals, ERROR)
SetLevel("TRACE")
c.Assert(Level, Equals, TRACE)
}
func (s *LogSuite) TestLog(c *C) {
logFile, err := os.OpenFile("tmptestfile.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
c.Check(err, IsNil)
defer logFile.Close()
defer os.Remove("tmptestfile.txt")
SetOutput(logFile)
num, err := lineCounter(logFile)
c.Check(num, Equals, 0)
c.Check(err, IsNil)
tmpFile, _ := os.Open("tmptestfile.txt")
Level = ERROR
Trace("a")
Debug("a")
Info("a")
Warn("a")
Error("a")
num, err = lineCounter(tmpFile)
c.Check(num, Equals, 1)
c.Check(err, IsNil)
tmpFile.Close()
tmpFile, _ = os.Open("tmptestfile.txt")
Level = WARN
Trace("a")
Debug("a")
Info("a")
Warn("a")
Error("a")
num, err = lineCounter(tmpFile)
c.Check(num, Equals, 3)
c.Check(err, IsNil)
tmpFile.Close()
tmpFile, _ = os.Open("tmptestfile.txt")
Level = INFO
Trace("a")
Debug("a")
Info("a")
Warn("a")
Error("a")
num, err = lineCounter(tmpFile)
c.Check(num, Equals, 6)
c.Check(err, IsNil)
tmpFile.Close()
tmpFile, _ = os.Open("tmptestfile.txt")
Level = DEBUG
Trace("a")
Debug("a")
Info("a")
Warn("a")
Error("a")
num, err = lineCounter(tmpFile)
c.Check(num, Equals, 10)
c.Check(err, IsNil)
tmpFile.Close()
tmpFile, _ = os.Open("tmptestfile.txt")
Level = TRACE
Trace("a")
Debug("a")
Info("a")
Warn("a")
Error("a")
num, err = lineCounter(tmpFile)
c.Check(num, Equals, 15)
c.Check(err, IsNil)
tmpFile.Close()
}
// Taken from http://stackoverflow.com/a/24563853/1187471
func lineCounter(r io.Reader) (int, error) {
buf := make([]byte, 8196)
count := 0
lineSep := []byte{'\n'}
for {
c, err := r.Read(buf)
if err != nil && err != io.EOF {
return count, err
}
count += bytes.Count(buf[:c], lineSep)
if err == io.EOF {
break
}
}
return count, nil
}

@ -16,14 +16,15 @@ import (
"net/http"
"os"
"os/signal"
"os/user"
"path/filepath"
"runtime"
"runtime/pprof"
"strings"
"time"
"github.com/otoolep/rqlite/log"
"github.com/otoolep/rqlite/server"
log "code.google.com/p/log4go"
)
var host string
@ -52,44 +53,6 @@ func init() {
}
}
func setupLogging(loggingLevel, logFile string) {
level := log.DEBUG
switch loggingLevel {
case "TRACE":
level = log.TRACE
case "DEBUG":
level = log.DEBUG
case "INFO":
level = log.INFO
case "WARN":
level = log.WARNING
case "ERROR":
level = log.ERROR
}
log.Global = make(map[string]*log.Filter)
if logFile == "stdout" {
flw := log.NewConsoleLogWriter()
log.AddFilter("stdout", level, flw)
} else {
logFileDir := filepath.Dir(logFile)
os.MkdirAll(logFileDir, 0744)
flw := log.NewFileLogWriter(logFile, false)
log.AddFilter("file", level, flw)
flw.SetFormat("[%D %T] [%L] (%S) %M")
flw.SetRotate(true)
flw.SetRotateSize(0)
flw.SetRotateLines(0)
flw.SetRotateDaily(true)
}
log.Info("Redirectoring logging to %s", logFile)
}
func main() {
flag.Parse()
@ -98,14 +61,23 @@ func main() {
log.Info("Profiling enabled")
f, err := os.Create(cpuprofile)
if err != nil {
log.Error("Unable to create path: %s", err.Error())
log.Errorf("Unable to create path: %s", err.Error())
}
defer f.Close()
defer closeFile(f)
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
setupLogging(logLevel, logFile)
// Set logging
log.SetLevel(logLevel)
if logFile != "stdout" {
f := createFile(logFile)
defer closeFile(f)
log.Infof("Redirecting logging to %s", logFile)
log.SetOutput(f)
}
// Set the data directory.
if flag.NArg() == 0 {
@ -116,12 +88,12 @@ func main() {
}
path := flag.Arg(0)
if err := os.MkdirAll(path, 0744); err != nil {
log.Error("Unable to create path: %s", err.Error())
log.Errorf("Unable to create path: %s", err.Error())
}
s := server.NewServer(path, dbfile, snapAfter, host, port)
go func() {
log.Error(s.ListenAndServe(join))
log.Error(s.ListenAndServe(join).Error())
}()
if !disableReporting {
@ -134,6 +106,36 @@ func main() {
log.Info("rqlite server stopped")
}
func closeFile(f *os.File) {
if err := f.Close(); err != nil {
log.Errorf("Unable to close file: %s", err.Error())
os.Exit(1)
}
}
func createFile(path string) *os.File {
usr, _ := user.Current()
dir := usr.HomeDir
// Check in case of paths like "/something/~/something/"
if path[:2] == "~/" {
path = strings.Replace(path, "~/", dir+"/", 1)
}
if err := os.MkdirAll(filepath.Dir(path), 0744); err != nil {
log.Errorf("Unable to create path: %s", err.Error())
os.Exit(1)
}
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Errorf("Unable to open file: %s", err.Error())
os.Exit(1)
}
return f
}
func reportLaunch() {
json := fmt.Sprintf(`{"os": "%s", "arch": "%s", "app": "rqlite"}`, runtime.GOOS, runtime.GOARCH)
data := bytes.NewBufferString(json)

@ -20,9 +20,8 @@ import (
"github.com/otoolep/rqlite/command"
"github.com/otoolep/rqlite/db"
"github.com/otoolep/rqlite/interfaces"
"github.com/otoolep/rqlite/log"
"github.com/rcrowley/go-metrics"
log "code.google.com/p/log4go"
)
type FailedSqlStmt struct {
@ -213,9 +212,9 @@ func (s *Server) connectionString() string {
func (s *Server) logSnapshot(err error, currentIndex, count uint64) {
info := fmt.Sprintf("%s: snapshot of %d events at index %d", s.connectionString, count, currentIndex)
if err != nil {
log.Info("%s attempted and failed: %v", info, err)
log.Infof("%s attempted and failed: %v", info, err)
} else {
log.Info("%s completed", info)
log.Infof("%s completed", info)
}
}
@ -223,21 +222,21 @@ func (s *Server) logSnapshot(err error, currentIndex, count uint64) {
func (s *Server) ListenAndServe(leader string) error {
var err error
log.Info("Initializing Raft Server: %s", s.path)
log.Infof("Initializing Raft Server: %s", s.path)
// Initialize and start Raft server.
transporter := raft.NewHTTPTransporter("/raft", 200*time.Millisecond)
stateMachine := NewDbStateMachine(s.dbPath)
s.raftServer, err = raft.NewServer(s.name, s.path, transporter, stateMachine, s.db, "")
if err != nil {
log.Error("Failed to create new Raft server", err.Error())
log.Errorf("Failed to create new Raft server: %s", err.Error())
return err
}
log.Info("Loading latest snapshot, if any, from disk")
err = s.raftServer.LoadSnapshot()
if err != nil {
log.Error("Error loading snapshot: %s", err.Error())
log.Errorf("Error loading snapshot: %s", err.Error())
}
transporter.Install(s.raftServer, s)
@ -246,14 +245,14 @@ func (s *Server) ListenAndServe(leader string) error {
if leader != "" {
// Join to leader if specified.
log.Info("Attempting to join leader at %s", leader)
log.Infof("Attempting to join leader at %s", leader)
if !s.raftServer.IsLogEmpty() {
log.Error("Cannot join with an existing log")
return errors.New("Cannot join with an existing log")
}
if err := s.Join(leader); err != nil {
log.Error("Failed to join leader", err.Error())
log.Errorf("Failed to join leader: %s", err.Error())
return err
}
@ -267,7 +266,7 @@ func (s *Server) ListenAndServe(leader string) error {
ConnectionString: s.connectionString(),
})
if err != nil {
log.Error("Failed to join to self", err.Error())
log.Errorf("Failed to join to self: %", err.Error())
}
} else {
@ -289,7 +288,7 @@ func (s *Server) ListenAndServe(leader string) error {
s.router.HandleFunc("/db", s.writeHandler).Methods("POST")
s.router.HandleFunc("/join", s.joinHandler).Methods("POST")
log.Info("Listening at %s", s.connectionString())
log.Infof("Listening at %s", s.connectionString())
return s.httpServer.ListenAndServe()
}
@ -325,7 +324,7 @@ func (s *Server) Join(leader string) error {
if err != nil {
return errors.New("Failed to parse redirect location")
}
log.Info("Redirecting to leader at %s", u.Host)
log.Infof("Redirecting to leader at %s", u.Host)
return s.Join(u.Host)
}
@ -357,14 +356,14 @@ func (s *Server) joinHandler(w http.ResponseWriter, req *http.Request) {
}
func (s *Server) readHandler(w http.ResponseWriter, req *http.Request) {
log.Trace("readHandler for URL: %s", req.URL)
log.Tracef("readHandler for URL: %s", req.URL)
s.metrics.queryReceived.Inc(1)
var failures = make([]FailedSqlStmt, 0)
b, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Trace("Bad HTTP request", err.Error())
log.Tracef("Bad HTTP request: %s", err.Error())
w.WriteHeader(http.StatusBadRequest)
s.metrics.queryFail.Inc(1)
return
@ -374,7 +373,7 @@ func (s *Server) readHandler(w http.ResponseWriter, req *http.Request) {
startTime := time.Now()
r, err := s.db.Query(stmt)
if err != nil {
log.Trace("Bad SQL statement", err.Error())
log.Tracef("Bad SQL statement: %s", err.Error())
s.metrics.queryFail.Inc(1)
failures = append(failures, FailedSqlStmt{stmt, err.Error()})
} else {
@ -390,7 +389,7 @@ func (s *Server) readHandler(w http.ResponseWriter, req *http.Request) {
b, err = json.Marshal(rr)
}
if err != nil {
log.Trace("Failed to marshal JSON data", err.Error())
log.Tracef("Failed to marshal JSON data: %s", err.Error())
http.Error(w, err.Error(), http.StatusBadRequest) // Internal error actually
} else {
w.Write([]byte(b))
@ -406,7 +405,7 @@ func (s *Server) execute(tx bool, stmts []string) ([]FailedSqlStmt, error) {
_, err := s.raftServer.Do(command.NewTransactionExecuteCommandSet(stmts))
if err != nil {
log.Trace("Transaction failed: %s", err.Error())
log.Tracef("Transaction failed: %s", err.Error())
s.metrics.executeFail.Inc(1)
failures = append(failures, FailedSqlStmt{stmts[0], err.Error()})
} else {
@ -417,7 +416,7 @@ func (s *Server) execute(tx bool, stmts []string) ([]FailedSqlStmt, error) {
for i := range stmts {
_, err := s.raftServer.Do(command.NewExecuteCommand(stmts[i]))
if err != nil {
log.Trace("Execute statement %s failed: %s", stmts[i], err.Error())
log.Tracef("Execute statement %s failed: %s", stmts[i], err.Error())
s.metrics.executeFail.Inc(1)
failures = append(failures, FailedSqlStmt{stmts[i], err.Error()})
} else {
@ -439,7 +438,7 @@ func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
return
}
log.Trace("writeHandler for URL: %s", req.URL)
log.Tracef("writeHandler for URL: %s", req.URL)
s.metrics.executeReceived.Inc(1)
currentIndex := s.raftServer.CommitIndex()
@ -457,7 +456,7 @@ func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
// Read the value from the POST body.
b, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Trace("Bad HTTP request", err.Error())
log.Tracef("Bad HTTP request: %s", err.Error())
s.metrics.executeFail.Inc(1)
w.WriteHeader(http.StatusBadRequest)
return
@ -467,7 +466,7 @@ func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
stmts = stmts[:len(stmts)-1]
}
log.Trace("Execute statement contains %d commands", len(stmts))
log.Tracef("Execute statement contains %d commands", len(stmts))
if len(stmts) == 0 {
log.Trace("No database execute commands supplied")
s.metrics.executeFail.Inc(1)
@ -479,7 +478,7 @@ func (s *Server) writeHandler(w http.ResponseWriter, req *http.Request) {
startTime = time.Now()
failures, err := s.execute(transaction, stmts)
if err != nil {
log.Error("Database mutation failed: %s", err.Error())
log.Errorf("Database mutation failed: %s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

@ -4,7 +4,7 @@ import (
"io/ioutil"
"os"
log "code.google.com/p/log4go"
"github.com/otoolep/rqlite/log"
)
type DbStateMachine struct {
@ -17,7 +17,7 @@ func NewDbStateMachine(path string) *DbStateMachine {
d := &DbStateMachine{
dbpath: path,
}
log.Trace("New DB state machine created with path: %s", path)
log.Tracef("New DB state machine created with path: %s", path)
return d
}
@ -27,24 +27,24 @@ func NewDbStateMachine(path string) *DbStateMachine {
// http://sqlite.org/howtocorrupt.html states it is safe to do this
// as long as no transaction is in progress.
func (d *DbStateMachine) Save() ([]byte, error) {
log.Trace("Capturing database state from path: %s", d.dbpath)
log.Tracef("Capturing database state from path: %s", d.dbpath)
b, err := ioutil.ReadFile(d.dbpath)
if err != nil {
log.Error("Failed to save state: ", err.Error())
log.Errorf("Failed to save state: %s", err.Error())
return nil, err
}
log.Trace("Database state successfully saved to %s", d.dbpath)
log.Tracef("Database state successfully saved to %s", d.dbpath)
return b, nil
}
// Recovery restores the state of the database using the given data.
func (d *DbStateMachine) Recovery(b []byte) error {
log.Trace("Restoring database state to path: %s", d.dbpath)
log.Tracef("Restoring database state to path: %s", d.dbpath)
err := ioutil.WriteFile(d.dbpath, b, os.ModePerm)
if err != nil {
log.Error("Failed to recover state: ", err.Error())
log.Errorf("Failed to recover state: %s", err.Error())
return err
}
log.Trace("Database restored successfully to %s", d.dbpath)
log.Tracef("Database restored successfully to %s", d.dbpath)
return nil
}

Loading…
Cancel
Save