Export the logger (again)
Just enabling or disabling logging falls short of the power of interfaces of go. A user is forced to either accept the logging to stderr in the format defined by xgb or disable logging alltogether. By exporting the logger, we can actually let the user decide where to log in what format.
This commit is contained in:
parent
38b293e74d
commit
2104b8fcdf
|
@ -33,8 +33,8 @@ func (c *Conn) connect(display string) error {
|
||||||
authName, authData, err := readAuthority(c.host, c.display)
|
authName, authData, err := readAuthority(c.host, c.display)
|
||||||
noauth := false
|
noauth := false
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("Could not get authority info: %v", err)
|
Logger.Printf("Could not get authority info: %v", err)
|
||||||
logger.Println("Trying connection without authority info...")
|
Logger.Println("Trying connection without authority info...")
|
||||||
authName = ""
|
authName = ""
|
||||||
authData = []byte{}
|
authData = []byte{}
|
||||||
noauth = true
|
noauth = true
|
||||||
|
|
85
nexgb/log.go
85
nexgb/log.go
|
@ -1,85 +0,0 @@
|
||||||
package xgb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Log controls whether XGB emits errors to stderr. By default, it is enabled.
|
|
||||||
var PrintLog = true
|
|
||||||
|
|
||||||
// log is a wrapper around a log.PrintLogger so we can control whether it should
|
|
||||||
// output anything.
|
|
||||||
type xgblog struct {
|
|
||||||
*log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLogger() xgblog {
|
|
||||||
return xgblog{log.New(os.Stderr, "XGB: ", log.Lshortfile)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Print(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Print(v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Printf(format string, v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Printf(format, v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Println(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Println(v...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Fatal(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Fatal(v...)
|
|
||||||
} else {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Fatalf(format string, v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Fatalf(format, v...)
|
|
||||||
} else {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Fatalln(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Fatalln(v...)
|
|
||||||
} else {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Panic(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Panic(v...)
|
|
||||||
} else {
|
|
||||||
panic("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Panicf(format string, v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Panicf(format, v...)
|
|
||||||
} else {
|
|
||||||
panic("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (lg xgblog) Panicln(v ...interface{}) {
|
|
||||||
if PrintLog {
|
|
||||||
lg.Logger.Panicln(v...)
|
|
||||||
} else {
|
|
||||||
panic("")
|
|
||||||
}
|
|
||||||
}
|
|
28
nexgb/xgb.go
28
nexgb/xgb.go
|
@ -3,12 +3,16 @@ package xgb
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logger = newLogger()
|
// Where to log error-messages. Defaults to stderr.
|
||||||
|
// To disable logging, just set this to log.New(ioutil.Discard, "", 0)
|
||||||
|
Logger = log.New(os.Stderr, "XGB: ", log.Lshortfile)
|
||||||
|
|
||||||
// ExtLock is a lock used whenever new extensions are initialized.
|
// ExtLock is a lock used whenever new extensions are initialized.
|
||||||
// It should not be used. It is exported for use in the extension
|
// It should not be used. It is exported for use in the extension
|
||||||
|
@ -328,8 +332,8 @@ func (c *Conn) noop() {
|
||||||
// writeBuffer is a convenience function for writing a byte slice to the wire.
|
// writeBuffer is a convenience function for writing a byte slice to the wire.
|
||||||
func (c *Conn) writeBuffer(buf []byte) {
|
func (c *Conn) writeBuffer(buf []byte) {
|
||||||
if _, err := c.conn.Write(buf); err != nil {
|
if _, err := c.conn.Write(buf); err != nil {
|
||||||
logger.Printf("Write error: %s", err)
|
Logger.Printf("Write error: %s", err)
|
||||||
logger.Fatal("A write error is unrecoverable. Exiting...")
|
Logger.Fatal("A write error is unrecoverable. Exiting...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +368,7 @@ func (c *Conn) readResponses() {
|
||||||
err, event, seq = nil, nil, 0
|
err, event, seq = nil, nil, 0
|
||||||
|
|
||||||
if _, err := io.ReadFull(c.conn, buf); err != nil {
|
if _, err := io.ReadFull(c.conn, buf); err != nil {
|
||||||
logger.Println("A read error is unrecoverable.")
|
Logger.Println("A read error is unrecoverable.")
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +378,7 @@ func (c *Conn) readResponses() {
|
||||||
// generated) by looking it up by the error number.
|
// generated) by looking it up by the error number.
|
||||||
newErrFun, ok := NewErrorFuncs[int(buf[1])]
|
newErrFun, ok := NewErrorFuncs[int(buf[1])]
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Printf("BUG: Could not find error constructor function "+
|
Logger.Printf("BUG: Could not find error constructor function "+
|
||||||
"for error with number %d.", buf[1])
|
"for error with number %d.", buf[1])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -393,8 +397,8 @@ func (c *Conn) readResponses() {
|
||||||
biggerBuf := make([]byte, byteCount)
|
biggerBuf := make([]byte, byteCount)
|
||||||
copy(biggerBuf[:32], buf)
|
copy(biggerBuf[:32], buf)
|
||||||
if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil {
|
if _, err := io.ReadFull(c.conn, biggerBuf[32:]); err != nil {
|
||||||
logger.Printf("Read error: %s", err)
|
Logger.Printf("Read error: %s", err)
|
||||||
logger.Fatal("A read error is unrecoverable. Exiting...")
|
Logger.Fatal("A read error is unrecoverable. Exiting...")
|
||||||
}
|
}
|
||||||
replyBytes = biggerBuf
|
replyBytes = biggerBuf
|
||||||
} else {
|
} else {
|
||||||
|
@ -411,7 +415,7 @@ func (c *Conn) readResponses() {
|
||||||
evNum := int(buf[0] & 127)
|
evNum := int(buf[0] & 127)
|
||||||
newEventFun, ok := NewEventFuncs[evNum]
|
newEventFun, ok := NewEventFuncs[evNum]
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Printf("BUG: Could not find event construct function "+
|
Logger.Printf("BUG: Could not find event construct function "+
|
||||||
"for event with number %d.", evNum)
|
"for event with number %d.", evNum)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -461,7 +465,7 @@ func (c *Conn) readResponses() {
|
||||||
}
|
}
|
||||||
} else { // this is a reply
|
} else { // this is a reply
|
||||||
if cookie.replyChan == nil {
|
if cookie.replyChan == nil {
|
||||||
logger.Printf("Reply with sequence id %d does not "+
|
Logger.Printf("Reply with sequence id %d does not "+
|
||||||
"have a cookie with a valid reply channel.", seq)
|
"have a cookie with a valid reply channel.", seq)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
|
@ -474,12 +478,12 @@ func (c *Conn) readResponses() {
|
||||||
switch {
|
switch {
|
||||||
// Checked requests with replies
|
// Checked requests with replies
|
||||||
case cookie.replyChan != nil && cookie.errorChan != nil:
|
case cookie.replyChan != nil && cookie.errorChan != nil:
|
||||||
logger.Printf("Found cookie with sequence id %d that is "+
|
Logger.Printf("Found cookie with sequence id %d that is "+
|
||||||
"expecting a reply but will never get it. Currently "+
|
"expecting a reply but will never get it. Currently "+
|
||||||
"on sequence number %d", cookie.Sequence, seq)
|
"on sequence number %d", cookie.Sequence, seq)
|
||||||
// Unchecked requests with replies
|
// Unchecked requests with replies
|
||||||
case cookie.replyChan != nil && cookie.pingChan != nil:
|
case cookie.replyChan != nil && cookie.pingChan != nil:
|
||||||
logger.Printf("Found cookie with sequence id %d that is "+
|
Logger.Printf("Found cookie with sequence id %d that is "+
|
||||||
"expecting a reply (and not an error) but will never "+
|
"expecting a reply (and not an error) but will never "+
|
||||||
"get it. Currently on sequence number %d",
|
"get it. Currently on sequence number %d",
|
||||||
cookie.Sequence, seq)
|
cookie.Sequence, seq)
|
||||||
|
@ -502,7 +506,7 @@ func processEventOrError(everr eventOrError) (Event, Error) {
|
||||||
case Error:
|
case Error:
|
||||||
return nil, ee
|
return nil, ee
|
||||||
default:
|
default:
|
||||||
logger.Printf("Invalid event/error type: %T", everr)
|
Logger.Printf("Invalid event/error type: %T", everr)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
|
|
Loading…
Reference in New Issue