Use loggo for logging

debian 0.1.0
Jan Dittberner 7 years ago
parent fd0a8ed972
commit 5a449926f4

@ -11,23 +11,22 @@ import (
"github.com/Masterminds/sprig" "github.com/Masterminds/sprig"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/juju/loggo"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"html/template" "html/template"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"os"
"strconv" "strconv"
"strings" "strings"
"time" "time"
) )
var logger *log.Logger
var config *Config var config *Config
var store *sessions.CookieStore var store *sessions.CookieStore
var version = "undefined" var version = "undefined"
var build = "undefined" var build = "undefined"
var logger loggo.Logger
const sessionCookieName = "votesession" const sessionCookieName = "votesession"
@ -243,13 +242,13 @@ type FlashMessageAction struct{}
func (a *FlashMessageAction) AddFlash(w http.ResponseWriter, r *http.Request, message interface{}, tags ...string) (err error) { func (a *FlashMessageAction) AddFlash(w http.ResponseWriter, r *http.Request, message interface{}, tags ...string) (err error) {
session, err := store.Get(r, sessionCookieName) session, err := store.Get(r, sessionCookieName)
if err != nil { if err != nil {
logger.Println("ERROR getting session:", err) logger.Errorf("getting session failed: %s", err)
return return
} }
session.AddFlash(message, tags...) session.AddFlash(message, tags...)
session.Save(r, w) session.Save(r, w)
if err != nil { if err != nil {
logger.Println("ERROR saving session:", err) logger.Errorf("saving session failed: %s", err)
return return
} }
return return
@ -283,7 +282,7 @@ func (a *withDrawMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
decision.Status = voteStatusWithdrawn decision.Status = voteStatusWithdrawn
decision.Modified = time.Now().UTC() decision.Modified = time.Now().UTC()
if err := decision.UpdateStatus(); err != nil { if err := decision.UpdateStatus(); err != nil {
logger.Println("Error withdrawing motion:", err) logger.Errorf("withdrawing motion failed: %s", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -336,7 +335,7 @@ func (h *newMotionHandler) Handle(w http.ResponseWriter, r *http.Request) {
data.Proposed = time.Now().UTC() data.Proposed = time.Now().UTC()
data.ProponentId = voter.Id data.ProponentId = voter.Id
if err := data.Create(); err != nil { if err := data.Create(); err != nil {
logger.Println("Error saving motion:", err) logger.Errorf("saving motion failed: %s", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -401,7 +400,7 @@ func (a editMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
} else { } else {
data.Modified = time.Now().UTC() data.Modified = time.Now().UTC()
if err := data.Update(); err != nil { if err := data.Update(); err != nil {
logger.Println("Error updating motion:", err) logger.Errorf("updating motion failed: %s", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -431,10 +430,6 @@ func (a editMotionAction) Handle(w http.ResponseWriter, r *http.Request) {
type motionsHandler struct{} type motionsHandler struct{}
func (h motionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h motionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := db.Ping(); err != nil {
logger.Fatal(err)
}
subURL := r.URL.Path subURL := r.URL.Path
var motionActionMap = map[string]motionActionHandler{ var motionActionMap = map[string]motionActionHandler{
@ -505,7 +500,7 @@ func (h *directVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
VoterId: voter.Id, Vote: vote, DecisionId: decision.Id, Voted: time.Now().UTC(), VoterId: voter.Id, Vote: vote, DecisionId: decision.Id, Voted: time.Now().UTC(),
Notes: fmt.Sprintf("Direct Vote\n\n%s", getPEMClientCert(r))} Notes: fmt.Sprintf("Direct Vote\n\n%s", getPEMClientCert(r))}
if err := voteResult.Save(); err != nil { if err := voteResult.Save(); err != nil {
logger.Println("ERROR", "Problem saving vote:", err) logger.Errorf("Problem saving vote: %s", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -589,7 +584,7 @@ func (h *proxyVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
proxy.Name, justification, getPEMClientCert(r)) proxy.Name, justification, getPEMClientCert(r))
if err := data.Save(); err != nil { if err := data.Save(); err != nil {
logger.Println("Error saving vote:", err) logger.Errorf("Error saving vote: %s", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
@ -620,10 +615,6 @@ func (h *proxyVoteHandler) Handle(w http.ResponseWriter, r *http.Request) {
type decisionVoteHandler struct{} type decisionVoteHandler struct{}
func (h *decisionVoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *decisionVoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := db.Ping(); err != nil {
logger.Fatal(err)
}
switch { switch {
case strings.HasPrefix(r.URL.Path, "/proxy/"): case strings.HasPrefix(r.URL.Path, "/proxy/"):
motionTag := r.URL.Path[len("/proxy/"):] motionTag := r.URL.Path[len("/proxy/"):]
@ -675,35 +666,42 @@ type Config struct {
} }
func init() { func init() {
logger = log.New(os.Stderr, "boardvoting: ", log.LstdFlags|log.LUTC|log.Lshortfile) loggo.ConfigureLoggers("<root>=ERROR; boardvoting=INFO")
logger = loggo.GetLogger("boardvoting")
logger.Infof("Logger initialized")
source, err := ioutil.ReadFile("config.yaml") source, err := ioutil.ReadFile("config.yaml")
if err != nil { if err != nil {
logger.Fatal(err) logger.Criticalf("Opening configuration file failed: %s", err)
panic(err)
} }
if err := yaml.Unmarshal(source, &config); err != nil { if err := yaml.Unmarshal(source, &config); err != nil {
logger.Fatal(err) logger.Criticalf("Loading configuration failed: %s", err)
panic(err)
} }
cookieSecret, err := base64.StdEncoding.DecodeString(config.CookieSecret) cookieSecret, err := base64.StdEncoding.DecodeString(config.CookieSecret)
if err != nil { if err != nil {
logger.Fatal(err) logger.Criticalf("Decoding cookie secret failed: %s", err)
panic(err)
} }
if len(cookieSecret) < 32 { if len(cookieSecret) < 32 {
logger.Fatalln("Cookie secret is less than 32 bytes long") logger.Criticalf("Cookie secret is less than 32 bytes long")
panic("Cookie secret too short")
} }
store = sessions.NewCookieStore(cookieSecret) store = sessions.NewCookieStore(cookieSecret)
logger.Println("read configuration") logger.Infof("Read configuration")
db, err = sqlx.Open("sqlite3", config.DatabaseFile) db, err = sqlx.Open("sqlite3", config.DatabaseFile)
if err != nil { if err != nil {
logger.Fatal(err) logger.Criticalf("Opening database failed: %s", err)
panic(err)
} }
logger.Println("opened database connection") logger.Infof("opened database connection")
} }
func main() { func main() {
logger.Printf("CAcert Board Voting version %s, build %s\n", version, build) logger.Infof("CAcert Board Voting version %s, build %s", version, build)
defer db.Close() defer db.Close()
@ -725,11 +723,13 @@ func main() {
// load CA certificates for client authentication // load CA certificates for client authentication
caCert, err := ioutil.ReadFile(config.ClientCACertificates) caCert, err := ioutil.ReadFile(config.ClientCACertificates)
if err != nil { if err != nil {
logger.Fatal(err) logger.Criticalf("Error reading client certificate CAs", err)
panic(err)
} }
caCertPool := x509.NewCertPool() caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM(caCert) { if !caCertPool.AppendCertsFromPEM(caCert) {
logger.Fatal("could not initialize client CA certificate pool") logger.Criticalf("could not initialize client CA certificate pool")
panic("client certificate CA pool initialization failed")
} }
// setup HTTPS server // setup HTTPS server
@ -744,7 +744,7 @@ func main() {
TLSConfig: tlsConfig, TLSConfig: tlsConfig,
} }
logger.Printf("Launching application on https://localhost%s/\n", server.Addr) logger.Infof("Launching application on https://localhost%s/", server.Addr)
errs := make(chan error, 1) errs := make(chan error, 1)
go func() { go func() {
@ -755,9 +755,11 @@ func main() {
}() }()
if err = server.ListenAndServeTLS(config.ServerCert, config.ServerKey); err != nil { if err = server.ListenAndServeTLS(config.ServerCert, config.ServerKey); err != nil {
logger.Fatal("ListenAndServerTLS: ", err) logger.Criticalf("ListenAndServerTLS failed: %s", err)
panic(err)
} }
if err := <-errs; err != nil { if err := <-errs; err != nil {
logger.Fatal("ListenAndServe: ", err) logger.Criticalf("ListenAndServe failed: %s", err)
panic(err)
} }
} }

@ -22,19 +22,19 @@ func JobScheduler(quitChannel chan int) {
JobIdCloseDecisions: NewCloseDecisionsJob(), JobIdCloseDecisions: NewCloseDecisionsJob(),
JobIdRemindVotersJob: NewRemindVotersJob(), JobIdRemindVotersJob: NewRemindVotersJob(),
} }
logger.Println("INFO started job scheduler") logger.Infof("started job scheduler")
for { for {
select { select {
case jobId := <-rescheduleChannel: case jobId := <-rescheduleChannel:
job := jobs[jobId] job := jobs[jobId]
logger.Println("INFO reschedule job", job) logger.Infof("reschedule job %s", job)
job.Schedule() job.Schedule()
case <-quitChannel: case <-quitChannel:
for _, job := range jobs { for _, job := range jobs {
job.Stop() job.Stop()
} }
logger.Println("INFO stop job scheduler") logger.Infof("stop job scheduler")
return return
} }
} }
@ -54,7 +54,7 @@ func (j *CloseDecisionsJob) Schedule() {
var nextDue *time.Time var nextDue *time.Time
nextDue, err := GetNextPendingDecisionDue() nextDue, err := GetNextPendingDecisionDue()
if err != nil { if err != nil {
logger.Fatal("ERROR Could not get next pending due date") logger.Errorf("Could not get next pending due date")
if j.timer != nil { if j.timer != nil {
j.timer.Stop() j.timer.Stop()
j.timer = nil j.timer = nil
@ -62,11 +62,11 @@ func (j *CloseDecisionsJob) Schedule() {
return return
} }
if nextDue == nil { if nextDue == nil {
logger.Println("INFO no next planned execution of CloseDecisionsJob") logger.Infof("no next planned execution of CloseDecisionsJob")
j.Stop() j.Stop()
} else { } else {
nextDue := nextDue.Add(time.Minute) nextDue := nextDue.Add(time.Minute)
logger.Println("INFO scheduling CloseDecisionsJob for", nextDue) logger.Infof("scheduling CloseDecisionsJob for %s", nextDue)
when := nextDue.Sub(time.Now()) when := nextDue.Sub(time.Now())
if j.timer != nil { if j.timer != nil {
j.timer.Reset(when) j.timer.Reset(when)
@ -84,10 +84,10 @@ func (j *CloseDecisionsJob) Stop() {
} }
func (j *CloseDecisionsJob) Run() { func (j *CloseDecisionsJob) Run() {
logger.Println("INFO running CloseDecisionsJob") logger.Infof("running CloseDecisionsJob")
err := CloseDecisions() err := CloseDecisions()
if err != nil { if err != nil {
logger.Println("ERROR closing decisions", err) logger.Errorf("closing decisions %s", err)
} }
rescheduleChannel <- JobIdCloseDecisions rescheduleChannel <- JobIdCloseDecisions
} }
@ -109,7 +109,7 @@ func NewRemindVotersJob() *RemindVotersJob {
func (j *RemindVotersJob) Schedule() { func (j *RemindVotersJob) Schedule() {
year, month, day := time.Now().UTC().Date() year, month, day := time.Now().UTC().Date()
nextExecution := time.Date(year, month, day, 0, 0, 0, 0, time.UTC).AddDate(0, 0, 3) nextExecution := time.Date(year, month, day, 0, 0, 0, 0, time.UTC).AddDate(0, 0, 3)
logger.Println("INFO scheduling RemindVotersJob for", nextExecution) logger.Infof("scheduling RemindVotersJob for %s", nextExecution)
when := nextExecution.Sub(time.Now()) when := nextExecution.Sub(time.Now())
if j.timer != nil { if j.timer != nil {
j.timer.Reset(when) j.timer.Reset(when)
@ -126,19 +126,19 @@ func (j *RemindVotersJob) Stop() {
} }
func (j *RemindVotersJob) Run() { func (j *RemindVotersJob) Run() {
logger.Println("INFO running RemindVotersJob") logger.Infof("running RemindVotersJob")
defer func() { rescheduleChannel <- JobIdRemindVotersJob }() defer func() { rescheduleChannel <- JobIdRemindVotersJob }()
voters, err := GetReminderVoters() voters, err := GetReminderVoters()
if err != nil { if err != nil {
logger.Println("ERROR problem getting voters", err) logger.Errorf("problem getting voters %s", err)
return return
} }
for _, voter := range *voters { for _, voter := range *voters {
decisions, err := FindUnvotedDecisionsForVoter(&voter) decisions, err := FindUnvotedDecisionsForVoter(&voter)
if err != nil { if err != nil {
logger.Println("ERROR problem getting unvoted decisions") logger.Errorf("problem getting unvoted decisions")
return return
} }
if len(*decisions) > 0 { if len(*decisions) > 0 {

@ -126,14 +126,19 @@ WHERE decision=$1 AND voter=$2`,
var db *sqlx.DB var db *sqlx.DB
func init() { func init() {
failed_statements := make([]string, 0)
for _, sqlStatement := range sqlStatements { for _, sqlStatement := range sqlStatements {
var stmt *sqlx.Stmt var stmt *sqlx.Stmt
stmt, err := db.Preparex(sqlStatement) stmt, err := db.Preparex(sqlStatement)
if err != nil { if err != nil {
logger.Fatalf("ERROR parsing statement %s: %s", sqlStatement, err) logger.Criticalf("ERROR parsing statement %s: %s", sqlStatement, err)
failed_statements = append(failed_statements, sqlStatement)
} }
stmt.Close() stmt.Close()
} }
if len(failed_statements) > 0 {
panic(fmt.Sprintf("%d statements failed", len(failed_statements)))
}
migrateConf := &goose.DBConf{ migrateConf := &goose.DBConf{
MigrationsDir: config.MigrationsPath, MigrationsDir: config.MigrationsPath,
@ -148,12 +153,14 @@ func init() {
latest, err := goose.GetMostRecentDBVersion(migrateConf.MigrationsDir) latest, err := goose.GetMostRecentDBVersion(migrateConf.MigrationsDir)
if err != nil { if err != nil {
logger.Panicln(err) logger.Criticalf("getting the most recent database repository version failed: %s", err)
panic(err)
} }
err = goose.RunMigrationsOnDb(migrateConf, migrateConf.MigrationsDir, latest, db.DB) err = goose.RunMigrationsOnDb(migrateConf, migrateConf.MigrationsDir, latest, db.DB)
if err != nil { if err != nil {
logger.Panicln(err) logger.Criticalf("running database migration failed: %s", err)
panic(err)
} }
} }
@ -278,27 +285,27 @@ type Vote struct {
func (v *Vote) Save() (err error) { func (v *Vote) Save() (err error) {
insertVoteStmt, err := db.PrepareNamed(sqlStatements[sqlCreateVote]) insertVoteStmt, err := db.PrepareNamed(sqlStatements[sqlCreateVote])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer insertVoteStmt.Close() defer insertVoteStmt.Close()
_, err = insertVoteStmt.Exec(v) _, err = insertVoteStmt.Exec(v)
if err != nil { if err != nil {
logger.Println("Error saving vote:", err) logger.Errorf("saving vote failed: %s", err)
return return
} }
getVoteStmt, err := db.Preparex(sqlStatements[sqlLoadVote]) getVoteStmt, err := db.Preparex(sqlStatements[sqlLoadVote])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getVoteStmt.Close() defer getVoteStmt.Close()
err = getVoteStmt.Get(v, v.DecisionId, v.VoterId) err = getVoteStmt.Get(v, v.DecisionId, v.VoterId)
if err != nil { if err != nil {
logger.Println("Error getting inserted vote:", err) logger.Errorf("getting inserted vote failed: %s", err)
} }
return return
@ -341,7 +348,7 @@ type DecisionForDisplay struct {
func FindDecisionForDisplayByTag(tag string) (decision *DecisionForDisplay, err error) { func FindDecisionForDisplayByTag(tag string) (decision *DecisionForDisplay, err error) {
decisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionByTag]) decisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionByTag])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer decisionStmt.Close() defer decisionStmt.Close()
@ -352,7 +359,7 @@ func FindDecisionForDisplayByTag(tag string) (decision *DecisionForDisplay, err
decision = nil decision = nil
err = nil err = nil
} else { } else {
logger.Printf("Error getting motion %s: %v\n", tag, err) logger.Errorf("getting motion %s failed: %v", tag, err)
} }
} }
decision.VoteSums, err = decision.Decision.VoteSums() decision.VoteSums, err = decision.Decision.VoteSums()
@ -372,7 +379,7 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
decisionsStmt, err = db.Preparex(sqlStatements[sqlLoadDecisions]) decisionsStmt, err = db.Preparex(sqlStatements[sqlLoadDecisions])
} }
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer decisionsStmt.Close() defer decisionsStmt.Close()
@ -384,7 +391,7 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
rows, err = decisionsStmt.Queryx(page - 1) rows, err = decisionsStmt.Queryx(page - 1)
} }
if err != nil { if err != nil {
logger.Printf("Error loading motions for page %d: %v\n", page, err) logger.Errorf("loading motions for page %d failed: %v", page, err)
return return
} }
defer rows.Close() defer rows.Close()
@ -392,7 +399,7 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
for rows.Next() { for rows.Next() {
var d DecisionForDisplay var d DecisionForDisplay
if err = rows.StructScan(&d); err != nil { if err = rows.StructScan(&d); err != nil {
logger.Printf("Error loading motions for page %d: %v\n", page, err) logger.Errorf("loading motions for page %d failed: %v", page, err)
return return
} }
d.VoteSums, err = d.Decision.VoteSums() d.VoteSums, err = d.Decision.VoteSums()
@ -407,14 +414,14 @@ func FindDecisionsForDisplayOnPage(page int64, unvoted bool, voter *Voter) (deci
func (d *Decision) VoteSums() (sums *VoteSums, err error) { func (d *Decision) VoteSums() (sums *VoteSums, err error) {
votesStmt, err := db.Preparex(sqlStatements[sqlLoadVoteCountsForDecision]) votesStmt, err := db.Preparex(sqlStatements[sqlLoadVoteCountsForDecision])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer votesStmt.Close() defer votesStmt.Close()
voteRows, err := votesStmt.Queryx(d.Id) voteRows, err := votesStmt.Queryx(d.Id)
if err != nil { if err != nil {
logger.Printf("Error fetching vote sums for motion %s: %v\n", d.Tag, err) logger.Errorf("fetching vote sums for motion %s failed: %v", d.Tag, err)
return return
} }
defer voteRows.Close() defer voteRows.Close()
@ -424,7 +431,7 @@ func (d *Decision) VoteSums() (sums *VoteSums, err error) {
var vote VoteChoice var vote VoteChoice
var count int var count int
if err = voteRows.Scan(&vote, &count); err != nil { if err = voteRows.Scan(&vote, &count); err != nil {
logger.Printf("Error fetching vote sums for motion %s: %v\n", d.Tag, err) logger.Errorf("fetching vote sums for motion %s failed: %v", d.Tag, err)
return return
} }
switch vote { switch vote {
@ -442,13 +449,13 @@ func (d *Decision) VoteSums() (sums *VoteSums, err error) {
func (d *DecisionForDisplay) LoadVotes() (err error) { func (d *DecisionForDisplay) LoadVotes() (err error) {
votesStmt, err := db.Preparex(sqlStatements[sqlLoadVotesForDecision]) votesStmt, err := db.Preparex(sqlStatements[sqlLoadVotesForDecision])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer votesStmt.Close() defer votesStmt.Close()
err = votesStmt.Select(&d.Votes, d.Id) err = votesStmt.Select(&d.Votes, d.Id)
if err != nil { if err != nil {
logger.Printf("Error selecting votes for motion %s: %v\n", d.Tag, err) logger.Errorf("selecting votes for motion %s failed: %v", d.Tag, err)
} }
return return
} }
@ -461,18 +468,18 @@ func (d *Decision) OlderExists(unvoted bool, voter *Voter) (result bool, err err
olderStmt, err = db.Preparex(sqlStatements[sqlCountOlderThanDecision]) olderStmt, err = db.Preparex(sqlStatements[sqlCountOlderThanDecision])
} }
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer olderStmt.Close() defer olderStmt.Close()
if unvoted && voter != nil { if unvoted && voter != nil {
if err = olderStmt.Get(&result, d.Proposed, voter.Id); err != nil { if err = olderStmt.Get(&result, d.Proposed, voter.Id); err != nil {
logger.Printf("Error finding older motions than %s: %v\n", d.Tag, err) logger.Errorf("finding older motions than %s failed: %v", d.Tag, err)
} }
} else { } else {
if err = olderStmt.Get(&result, d.Proposed); err != nil { if err = olderStmt.Get(&result, d.Proposed); err != nil {
logger.Printf("Error finding older motions than %s: %v\n", d.Tag, err) logger.Errorf("finding older motions than %s failed: %v", d.Tag, err)
} }
} }
@ -482,34 +489,34 @@ func (d *Decision) OlderExists(unvoted bool, voter *Voter) (result bool, err err
func (d *Decision) Create() (err error) { func (d *Decision) Create() (err error) {
insertDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlCreateDecision]) insertDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlCreateDecision])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer insertDecisionStmt.Close() defer insertDecisionStmt.Close()
result, err := insertDecisionStmt.Exec(d) result, err := insertDecisionStmt.Exec(d)
if err != nil { if err != nil {
logger.Println("Error creating motion:", err) logger.Errorf("creating motion failed: %s", err)
return return
} }
lastInsertId, err := result.LastInsertId() lastInsertId, err := result.LastInsertId()
if err != nil { if err != nil {
logger.Println("Error getting id of inserted motion:", err) logger.Errorf("getting id of inserted motion failed: %s", err)
return return
} }
rescheduleChannel <- JobIdCloseDecisions rescheduleChannel <- JobIdCloseDecisions
getDecisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionById]) getDecisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionById])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getDecisionStmt.Close() defer getDecisionStmt.Close()
err = getDecisionStmt.Get(d, lastInsertId) err = getDecisionStmt.Get(d, lastInsertId)
if err != nil { if err != nil {
logger.Println("Error getting inserted motion:", err) logger.Errorf("getting inserted motion failed: %s", err)
} }
return return
@ -518,14 +525,14 @@ func (d *Decision) Create() (err error) {
func (d *Decision) LoadWithId() (err error) { func (d *Decision) LoadWithId() (err error) {
getDecisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionById]) getDecisionStmt, err := db.Preparex(sqlStatements[sqlLoadDecisionById])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getDecisionStmt.Close() defer getDecisionStmt.Close()
err = getDecisionStmt.Get(d, d.Id) err = getDecisionStmt.Get(d, d.Id)
if err != nil { if err != nil {
logger.Println("Error loading updated motion:", err) logger.Errorf("loading updated motion failed: %s", err)
} }
return return
@ -534,22 +541,22 @@ func (d *Decision) LoadWithId() (err error) {
func (d *Decision) Update() (err error) { func (d *Decision) Update() (err error) {
updateDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecision]) updateDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecision])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer updateDecisionStmt.Close() defer updateDecisionStmt.Close()
result, err := updateDecisionStmt.Exec(d) result, err := updateDecisionStmt.Exec(d)
if err != nil { if err != nil {
logger.Println("Error updating motion:", err) logger.Errorf("updating motion failed: %s", err)
return return
} }
affectedRows, err := result.RowsAffected() affectedRows, err := result.RowsAffected()
if err != nil { if err != nil {
logger.Print("Problem determining the affected rows") logger.Errorf("Problem determining the affected rows")
return return
} else if affectedRows != 1 { } else if affectedRows != 1 {
logger.Printf("WARNING wrong number of affected rows: %d (1 expected)\n", affectedRows) logger.Warningf("wrong number of affected rows: %d (1 expected)", affectedRows)
} }
rescheduleChannel <- JobIdCloseDecisions rescheduleChannel <- JobIdCloseDecisions
@ -560,22 +567,22 @@ func (d *Decision) Update() (err error) {
func (d *Decision) UpdateStatus() (err error) { func (d *Decision) UpdateStatus() (err error) {
updateStatusStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecisionStatus]) updateStatusStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecisionStatus])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer updateStatusStmt.Close() defer updateStatusStmt.Close()
result, err := updateStatusStmt.Exec(d) result, err := updateStatusStmt.Exec(d)
if err != nil { if err != nil {
logger.Println("Error setting motion status:", err) logger.Errorf("setting motion status failed: %s", err)
return return
} }
affectedRows, err := result.RowsAffected() affectedRows, err := result.RowsAffected()
if err != nil { if err != nil {
logger.Print("Problem determining the affected rows") logger.Errorf("determining the affected rows failed: %s", err)
return return
} else if affectedRows != 1 { } else if affectedRows != 1 {
logger.Printf("WARNING wrong number of affected rows: %d (1 expected)\n", affectedRows) logger.Warningf("wrong number of affected rows: %d (1 expected)", affectedRows)
} }
rescheduleChannel <- JobIdCloseDecisions rescheduleChannel <- JobIdCloseDecisions
@ -590,7 +597,7 @@ func (d *Decision) String() string {
func FindVoterByAddress(emailAddress string) (voter *Voter, err error) { func FindVoterByAddress(emailAddress string) (voter *Voter, err error) {
findVoterStmt, err := db.Preparex(sqlStatements[sqlLoadEnabledVoterByEmail]) findVoterStmt, err := db.Preparex(sqlStatements[sqlLoadEnabledVoterByEmail])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer findVoterStmt.Close() defer findVoterStmt.Close()
@ -598,7 +605,7 @@ func FindVoterByAddress(emailAddress string) (voter *Voter, err error) {
voter = &Voter{} voter = &Voter{}
if err = findVoterStmt.Get(voter, emailAddress); err != nil { if err = findVoterStmt.Get(voter, emailAddress); err != nil {
if err != sql.ErrNoRows { if err != sql.ErrNoRows {
logger.Printf("Error getting voter for address %s: %v\n", emailAddress, err) logger.Errorf("getting voter for address %s failed: %v", emailAddress, err)
} else { } else {
err = nil err = nil
voter = nil voter = nil
@ -613,7 +620,7 @@ func (d *Decision) Close() (err error) {
voteSums, err := d.VoteSums() voteSums, err := d.VoteSums()
if err != nil { if err != nil {
logger.Println("Error getting vote sums") logger.Errorf("getting vote sums failed: %s", err)
return return
} }
votes := voteSums.VoteCount() votes := voteSums.VoteCount()
@ -631,22 +638,22 @@ func (d *Decision) Close() (err error) {
closeDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecisionStatus]) closeDecisionStmt, err := db.PrepareNamed(sqlStatements[sqlUpdateDecisionStatus])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer closeDecisionStmt.Close() defer closeDecisionStmt.Close()
result, err := closeDecisionStmt.Exec(d) result, err := closeDecisionStmt.Exec(d)
if err != nil { if err != nil {
logger.Println("Error closing vote:", err) logger.Errorf("closing vote failed: %s", err)
return return
} }
affectedRows, err := result.RowsAffected() affectedRows, err := result.RowsAffected()
if err != nil { if err != nil {
logger.Println("Error getting affected rows:", err) logger.Errorf("getting affected rows failed: %s", err)
} }
if affectedRows != 1 { if affectedRows != 1 {
logger.Printf("WARNING wrong number of affected rows: %d (1 expected)\n", affectedRows) logger.Warningf("wrong number of affected rows: %d (1 expected)", affectedRows)
} }
NotifyMailChannel <- NewNotificationClosedDecision(d, voteSums) NotifyMailChannel <- NewNotificationClosedDecision(d, voteSums)
@ -657,7 +664,7 @@ func (d *Decision) Close() (err error) {
func CloseDecisions() (err error) { func CloseDecisions() (err error) {
getClosableDecisionsStmt, err := db.PrepareNamed(sqlStatements[sqlSelectClosableDecisions]) getClosableDecisionsStmt, err := db.PrepareNamed(sqlStatements[sqlSelectClosableDecisions])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getClosableDecisionsStmt.Close() defer getClosableDecisionsStmt.Close()
@ -665,14 +672,14 @@ func CloseDecisions() (err error) {
decisions := make([]*Decision, 0) decisions := make([]*Decision, 0)
rows, err := getClosableDecisionsStmt.Queryx(struct{ Now time.Time }{time.Now().UTC()}) rows, err := getClosableDecisionsStmt.Queryx(struct{ Now time.Time }{time.Now().UTC()})
if err != nil { if err != nil {
logger.Println("Error fetching closable decisions", err) logger.Errorf("fetching closable decisions failed: %s", err)
return return
} }
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
decision := &Decision{} decision := &Decision{}
if err = rows.StructScan(decision); err != nil { if err = rows.StructScan(decision); err != nil {
logger.Println("Error scanning row", err) logger.Errorf("scanning row failed: %s", err)
return return
} }
decisions = append(decisions, decision) decisions = append(decisions, decision)
@ -680,9 +687,9 @@ func CloseDecisions() (err error) {
rows.Close() rows.Close()
for _, decision := range decisions { for _, decision := range decisions {
logger.Println("DEBUG found closable decision", decision) logger.Debugf("found closable decision %s", decision.Tag)
if err = decision.Close(); err != nil { if err = decision.Close(); err != nil {
logger.Printf("Error closing decision %s: %s\n", decision, err) logger.Errorf("closing decision %s failed: %s", decision.Tag, err)
return return
} }
} }
@ -693,7 +700,7 @@ func CloseDecisions() (err error) {
func GetNextPendingDecisionDue() (due *time.Time, err error) { func GetNextPendingDecisionDue() (due *time.Time, err error) {
getNextPendingDecisionDueStmt, err := db.Preparex(sqlStatements[sqlGetNextPendingDecisionDue]) getNextPendingDecisionDueStmt, err := db.Preparex(sqlStatements[sqlGetNextPendingDecisionDue])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getNextPendingDecisionDueStmt.Close() defer getNextPendingDecisionDueStmt.Close()
@ -703,10 +710,10 @@ func GetNextPendingDecisionDue() (due *time.Time, err error) {
var dueTimestamp time.Time var dueTimestamp time.Time
if err = row.Scan(&dueTimestamp); err != nil { if err = row.Scan(&dueTimestamp); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
logger.Println("DEBUG No pending decisions") logger.Debugf("No pending decisions")
return nil, nil return nil, nil
} }
logger.Println("Error parsing result", err) logger.Errorf("parsing result failed: %s", err)
return return
} }
due = &dueTimestamp due = &dueTimestamp
@ -717,7 +724,7 @@ func GetNextPendingDecisionDue() (due *time.Time, err error) {
func GetReminderVoters() (voters *[]Voter, err error) { func GetReminderVoters() (voters *[]Voter, err error) {
getReminderVotersStmt, err := db.Preparex(sqlStatements[sqlGetReminderVoters]) getReminderVotersStmt, err := db.Preparex(sqlStatements[sqlGetReminderVoters])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getReminderVotersStmt.Close() defer getReminderVotersStmt.Close()
@ -725,7 +732,7 @@ func GetReminderVoters() (voters *[]Voter, err error) {
voterSlice := make([]Voter, 0) voterSlice := make([]Voter, 0)
if err = getReminderVotersStmt.Select(&voterSlice); err != nil { if err = getReminderVotersStmt.Select(&voterSlice); err != nil {
logger.Println("Error getting voters:", err) logger.Errorf("getting voters failed: %s", err)
return return
} }
voters = &voterSlice voters = &voterSlice
@ -736,7 +743,7 @@ func GetReminderVoters() (voters *[]Voter, err error) {
func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err error) { func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err error) {
findUnvotedDecisionsForVoterStmt, err := db.Preparex(sqlStatements[sqlFindUnvotedDecisionsForVoter]) findUnvotedDecisionsForVoterStmt, err := db.Preparex(sqlStatements[sqlFindUnvotedDecisionsForVoter])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer findUnvotedDecisionsForVoterStmt.Close() defer findUnvotedDecisionsForVoterStmt.Close()
@ -744,7 +751,7 @@ func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err erro
decisionsSlice := make([]Decision, 0) decisionsSlice := make([]Decision, 0)
if err = findUnvotedDecisionsForVoterStmt.Select(&decisionsSlice, voter.Id); err != nil { if err = findUnvotedDecisionsForVoterStmt.Select(&decisionsSlice, voter.Id); err != nil {
logger.Println("Error getting unvoted decisions:", err) logger.Errorf("getting unvoted decisions failed: %s", err)
return return
} }
decisions = &decisionsSlice decisions = &decisionsSlice
@ -755,14 +762,14 @@ func FindUnvotedDecisionsForVoter(voter *Voter) (decisions *[]Decision, err erro
func GetVoterById(id int64) (voter *Voter, err error) { func GetVoterById(id int64) (voter *Voter, err error) {
getVoterByIdStmt, err := db.Preparex(sqlStatements[sqlGetEnabledVoterById]) getVoterByIdStmt, err := db.Preparex(sqlStatements[sqlGetEnabledVoterById])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getVoterByIdStmt.Close() defer getVoterByIdStmt.Close()
voter = &Voter{} voter = &Voter{}
if err = getVoterByIdStmt.Get(voter, id); err != nil { if err = getVoterByIdStmt.Get(voter, id); err != nil {
logger.Println("Error getting voter:", err) logger.Errorf("getting voter failed: %s", err)
return return
} }
@ -772,7 +779,7 @@ func GetVoterById(id int64) (voter *Voter, err error) {
func GetVotersForProxy(proxy *Voter, decision *Decision) (voters *[]Voter, err error) { func GetVotersForProxy(proxy *Voter, decision *Decision) (voters *[]Voter, err error) {
getVotersForProxyStmt, err := db.Preparex(sqlStatements[sqlGetVotersForProxy]) getVotersForProxyStmt, err := db.Preparex(sqlStatements[sqlGetVotersForProxy])
if err != nil { if err != nil {
logger.Println("Error preparing statement:", err) logger.Errorf("preparing statement failed: %s", err)
return return
} }
defer getVotersForProxyStmt.Close() defer getVotersForProxyStmt.Close()
@ -780,7 +787,7 @@ func GetVotersForProxy(proxy *Voter, decision *Decision) (voters *[]Voter, err e
votersSlice := make([]Voter, 0) votersSlice := make([]Voter, 0)
if err = getVotersForProxyStmt.Select(&votersSlice, proxy.Id, decision.Id); err != nil { if err = getVotersForProxyStmt.Select(&votersSlice, proxy.Id, decision.Id); err != nil {
logger.Println("Error getting voters for proxy:", err) logger.Errorf("Error getting voters for proxy failed: %s", err)
return return
} }
voters = &votersSlice voters = &votersSlice

@ -34,14 +34,14 @@ type NotificationMail interface {
var NotifyMailChannel = make(chan NotificationMail, 1) var NotifyMailChannel = make(chan NotificationMail, 1)
func MailNotifier(quitMailNotifier chan int) { func MailNotifier(quitMailNotifier chan int) {
logger.Println("Launched mail notifier") logger.Infof("Launched mail notifier")
for { for {
select { select {
case notification := <-NotifyMailChannel: case notification := <-NotifyMailChannel:
content := notification.GetNotificationContent() content := notification.GetNotificationContent()
mailText, err := buildMail(content.template, content.data) mailText, err := buildMail(content.template, content.data)
if err != nil { if err != nil {
logger.Println("ERROR building mail:", err) logger.Errorf("building mail failed: %s", err)
continue continue
} }
@ -58,10 +58,10 @@ func MailNotifier(quitMailNotifier chan int) {
d := gomail.NewDialer(config.MailServer.Host, config.MailServer.Port, "", "") d := gomail.NewDialer(config.MailServer.Host, config.MailServer.Port, "", "")
if err := d.DialAndSend(m); err != nil { if err := d.DialAndSend(m); err != nil {
logger.Println("ERROR sending mail:", err) logger.Errorf("sending mail failed: %s", err)
} }
case <-quitMailNotifier: case <-quitMailNotifier:
fmt.Println("Ending mail notifier") logger.Infof("Ending mail notifier")
return return
} }
} }

Loading…
Cancel
Save