Add Logger interface to avoid logging directly (#161)

This commit adds a simple level-based log interface that allows users of the library to control and customize the output, for example by providing a standard Go logger with different settings (timestamps, prefixes, etc).

Closes #16. Closes #103.

Signed-off-by: Marcelo E. Magallon <marcelo.magallon@grafana.com>
This commit is contained in:
Marcelo Magallon 2021-04-02 17:25:49 -06:00 committed by GitHub
parent 80a5113803
commit 1726e5ede5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 2 deletions

53
logger.go Normal file
View File

@ -0,0 +1,53 @@
package ping
import "log"
type Logger interface {
Fatalf(format string, v ...interface{})
Errorf(format string, v ...interface{})
Warnf(format string, v ...interface{})
Infof(format string, v ...interface{})
Debugf(format string, v ...interface{})
}
type StdLogger struct {
Logger *log.Logger
}
func (l StdLogger) Fatalf(format string, v ...interface{}) {
l.Logger.Printf("FATAL: "+format, v...)
}
func (l StdLogger) Errorf(format string, v ...interface{}) {
l.Logger.Printf("ERROR: "+format, v...)
}
func (l StdLogger) Warnf(format string, v ...interface{}) {
l.Logger.Printf("WARN: "+format, v...)
}
func (l StdLogger) Infof(format string, v ...interface{}) {
l.Logger.Printf("INFO: "+format, v...)
}
func (l StdLogger) Debugf(format string, v ...interface{}) {
l.Logger.Printf("DEBUG: "+format, v...)
}
type NoopLogger struct {
}
func (l NoopLogger) Fatalf(format string, v ...interface{}) {
}
func (l NoopLogger) Errorf(format string, v ...interface{}) {
}
func (l NoopLogger) Warnf(format string, v ...interface{}) {
}
func (l NoopLogger) Infof(format string, v ...interface{}) {
}
func (l NoopLogger) Debugf(format string, v ...interface{}) {
}

18
ping.go
View File

@ -57,6 +57,7 @@ import (
"encoding/binary"
"errors"
"fmt"
"log"
"math"
"math/rand"
"net"
@ -102,6 +103,7 @@ func New(addr string) *Pinger {
network: "ip",
protocol: "udp",
awaitingSequences: map[int]struct{}{},
logger: StdLogger{Logger: log.New(log.Writer(), log.Prefix(), log.Flags())},
}
}
@ -192,6 +194,8 @@ type Pinger struct {
network string
// protocol is "icmp" or "udp".
protocol string
logger Logger
}
type packet struct {
@ -367,10 +371,20 @@ func (p *Pinger) Privileged() bool {
return p.protocol == "icmp"
}
// SetLogger sets the logger to be used to log events from the pinger.
func (p *Pinger) SetLogger(logger Logger) {
p.logger = logger
}
// Run runs the pinger. This is a blocking function that will exit when it's
// done. If Count or Interval are not specified, it will run continuously until
// it is interrupted.
func (p *Pinger) Run() error {
logger := p.logger
if logger == nil {
logger = NoopLogger{}
}
var conn *icmp.PacketConn
var err error
if p.ipaddr == nil {
@ -432,7 +446,7 @@ func (p *Pinger) Run() error {
err := p.processPacket(r)
if err != nil {
// FIXME: this logs as FATAL but continues
fmt.Println("FATAL:", err)
logger.Fatalf("processing received packet: %s", err)
}
case <-interval.C:
if p.Count > 0 && p.PacketsSent >= p.Count {
@ -442,7 +456,7 @@ func (p *Pinger) Run() error {
err = p.sendICMP(conn)
if err != nil {
// FIXME: this logs as FATAL but continues
fmt.Println("FATAL:", err)
logger.Fatalf("sending packet: %s", err)
}
}
if p.Count > 0 && p.PacketsRecv >= p.Count {