Initial changes to provide configurable logging options

This commit is contained in:
Kenneth Shaw 2017-02-13 16:00:25 +07:00
parent f55e04bb7a
commit 7326b390a0
3 changed files with 114 additions and 29 deletions

View File

@ -34,6 +34,9 @@ type CDP struct {
// handlerMap is the map of target IDs to its active handler.
handlerMap map[string]int
// logging funcs
logf, debugf, errorf LogFunc
sync.RWMutex
}
@ -44,6 +47,9 @@ func New(ctxt context.Context, opts ...Option) (*CDP, error) {
c := &CDP{
handlers: make([]*TargetHandler, 0),
handlerMap: make(map[string]int),
logf: log.Printf,
debugf: func(string, ...interface{}) {},
errorf: func(s string, v ...interface{}) { log.Printf("error: "+s, v...) },
}
// apply options
@ -108,16 +114,16 @@ func (c *CDP) AddTarget(ctxt context.Context, t client.Target) {
defer c.Unlock()
// create target manager
h, err := NewTargetHandler(t)
h, err := NewTargetHandler(t, c.logf, c.debugf, c.errorf)
if err != nil {
log.Printf("error: could not create handler for %s, got: %v", t, err)
c.errorf("could not create handler for %s, got: %v", t, err)
return
}
// run
err = h.Run(ctxt)
if err != nil {
log.Printf("error: could not start handler for %s, got: %v", t, err)
c.errorf("could not start handler for %s, got: %v", t, err)
return
}
@ -344,8 +350,8 @@ func (c *CDP) Run(ctxt context.Context, a Action) error {
// Option is a Chrome Debugging Protocol option.
type Option func(*CDP) error
// WithRunner is a option to specify the underlying Chrome runner to monitor
// for page handlers.
// WithRunner is a CDP option to specify the underlying Chrome runner to
// monitor for page handlers.
func WithRunner(r *runner.Runner) Option {
return func(c *CDP) error {
c.r = r
@ -353,8 +359,8 @@ func WithRunner(r *runner.Runner) Option {
}
}
// WithTargets is an option to specify the incoming targets to monitor for page
// handlers.
// WithTargets is a CDP option to specify the incoming targets to monitor for
// page handlers.
func WithTargets(watch <-chan client.Target) Option {
return func(c *CDP) error {
c.watch = watch
@ -362,7 +368,7 @@ func WithTargets(watch <-chan client.Target) Option {
}
}
// WithRunnerOptions is a option to specify the options to pass to a newly
// WithRunnerOptions is a CDP option to specify the options to pass to a newly
// created Chrome process runner.
func WithRunnerOptions(opts ...runner.CommandLineOption) Option {
return func(c *CDP) error {
@ -370,3 +376,51 @@ func WithRunnerOptions(opts ...runner.CommandLineOption) Option {
return nil
}
}
// LogFunc is the common logging func type.
type LogFunc func(string, ...interface{})
// WithLogf is a CDP option to specify a func to receive general logging.
func WithLogf(f LogFunc) Option {
return func(c *CDP) error {
c.logf = f
return nil
}
}
// WithDebugf is a CDP option to specify a func to receive debug logging (ie,
// protocol information).
func WithDebugf(f LogFunc) Option {
return func(c *CDP) error {
c.debugf = f
return nil
}
}
// WithErrorf is a CDP option to specify a func to receive error logging.
func WithErrorf(f LogFunc) Option {
return func(c *CDP) error {
c.errorf = f
return nil
}
}
// WithLog is a CDP option that sets the logging, debugging, and error funcs to
// f.
func WithLog(f LogFunc) Option {
return func(c *CDP) error {
c.logf = f
c.debugf = f
c.errorf = f
return nil
}
}
// WithConsolef is a CDP option to specify a func to receive chrome log events.
//
// Note: NOT YET IMPLEMENTED.
func WithConsolef(f LogFunc) Option {
return func(c *CDP) error {
return nil
}
}

View File

@ -3,7 +3,6 @@ package chromedp
import (
"context"
"fmt"
"log"
"reflect"
"runtime"
"strings"
@ -54,17 +53,25 @@ type TargetHandler struct {
res map[int64]chan interface{}
resrw sync.RWMutex
// logging funcs
logf, debugf, errorf LogFunc
sync.RWMutex
}
// NewTargetHandler creates a new handler for the specified client target.
func NewTargetHandler(t client.Target) (*TargetHandler, error) {
func NewTargetHandler(t client.Target, logf, debugf, errorf LogFunc) (*TargetHandler, error) {
conn, err := client.Dial(t)
if err != nil {
return nil, err
}
return &TargetHandler{conn: conn}, nil
return &TargetHandler{
conn: conn,
logf: logf,
debugf: debugf,
errorf: errorf,
}, nil
}
// Run starts the processing of commands and events of the client target
@ -154,7 +161,7 @@ func (h *TargetHandler) run(ctxt context.Context) {
h.qres <- msg
default:
log.Printf("ignoring malformed incoming message (missing id or method): %#v", msg)
h.errorf("ignoring malformed incoming message (missing id or method): %#v", msg)
}
case <-h.detached:
@ -175,19 +182,19 @@ func (h *TargetHandler) run(ctxt context.Context) {
case ev := <-h.qevents:
err = h.processEvent(ctxt, ev)
if err != nil {
log.Printf("could not process event, got: %v", err)
h.errorf("could not process event, got: %v", err)
}
case res := <-h.qres:
err = h.processResult(res)
if err != nil {
log.Printf("could not process command result, got: %v", err)
h.errorf("could not process command result, got: %v", err)
}
case cmd := <-h.qcmd:
err = h.processCommand(cmd)
if err != nil {
log.Printf("could not process command, got: %v", err)
h.errorf("could not process command, got: %v", err)
}
case <-ctxt.Done():
@ -204,7 +211,7 @@ func (h *TargetHandler) read() (*cdp.Message, error) {
return nil, err
}
log.Printf("-> %s", string(buf))
h.debugf("-> %s", string(buf))
// unmarshal
msg := new(cdp.Message)
@ -264,7 +271,7 @@ func (h *TargetHandler) processEvent(ctxt context.Context, msg *cdp.Message) err
func (h *TargetHandler) documentUpdated(ctxt context.Context) {
f, err := h.WaitFrame(ctxt, EmptyFrameID)
if err != nil {
log.Printf("could not get current frame, got: %v", err)
h.errorf("could not get current frame, got: %v", err)
return
}
@ -279,7 +286,7 @@ func (h *TargetHandler) documentUpdated(ctxt context.Context) {
f.Nodes = make(map[cdp.NodeID]*cdp.Node)
f.Root, err = dom.GetDocument().WithPierce(true).Do(ctxt, h)
if err != nil {
log.Printf("error could not retrieve document root for %s, got: %v", f.ID, err)
h.errorf("could not retrieve document root for %s, got: %v", f.ID, err)
return
}
f.Root.Invalidated = make(chan struct{})
@ -293,7 +300,9 @@ func (h *TargetHandler) processResult(msg *cdp.Message) error {
res, ok := h.res[msg.ID]
if !ok {
panic(fmt.Sprintf("expected result to be present for message id %d", msg.ID))
err := fmt.Errorf("expected result to be present for message id %d", msg.ID)
h.errorf(err.Error())
return err
}
if msg.Error != nil {
@ -316,7 +325,7 @@ func (h *TargetHandler) processCommand(cmd *cdp.Message) error {
return err
}
log.Printf("<- %s", string(buf))
h.debugf("<- %s", string(buf))
// write
return h.conn.Write(buf)
@ -539,12 +548,13 @@ func (h *TargetHandler) pageEvent(ctxt context.Context, ev interface{}) {
return
default:
panic(fmt.Sprintf("unhandled page event %s", reflect.TypeOf(ev)))
h.errorf("unhandled page event %s", reflect.TypeOf(ev))
return
}
f, err := h.WaitFrame(ctxt, id)
if err != nil {
log.Printf("error could not get frame %s, got: %v", id, err)
h.errorf("could not get frame %s, got: %v", id, err)
return
}
@ -564,7 +574,7 @@ func (h *TargetHandler) domEvent(ctxt context.Context, ev interface{}) {
// wait current frame
f, err := h.WaitFrame(ctxt, EmptyFrameID)
if err != nil {
log.Printf("error processing DOM event %s: error waiting for frame, got: %v", reflect.TypeOf(ev), err)
h.errorf("error processing DOM event %s: error waiting for frame, got: %v", reflect.TypeOf(ev), err)
return
}
@ -624,7 +634,8 @@ func (h *TargetHandler) domEvent(ctxt context.Context, ev interface{}) {
return
default:
panic(fmt.Sprintf("unhandled node event %s", reflect.TypeOf(ev)))
h.errorf("unhandled node event %s", reflect.TypeOf(ev))
return
}
s := strings.TrimPrefix(strings.TrimSuffix(runtime.FuncForPC(reflect.ValueOf(op).Pointer()).Name(), ".func1"), "github.com/knq/chromedp.")
@ -632,7 +643,7 @@ func (h *TargetHandler) domEvent(ctxt context.Context, ev interface{}) {
// retrieve node
n, err := h.WaitNode(ctxt, f, id)
if err != nil {
log.Printf("error could not perform (%s) operation on node %d (wait node error), got: %v", s, id, err)
h.errorf("error could not perform (%s) operation on node %d (wait node error), got: %v", s, id, err)
return
}

28
pool.go
View File

@ -3,6 +3,7 @@ package chromedp
import (
"context"
"fmt"
"log"
"sync"
"github.com/knq/chromedp/runner"
@ -19,6 +20,9 @@ type Pool struct {
// res are the running chrome resources.
res map[int]*Res
// logging funcs
logf, debugf, errorf LogFunc
rw sync.RWMutex
}
@ -27,9 +31,12 @@ func NewPool(opts ...PoolOption) (*Pool, error) {
var err error
p := &Pool{
start: DefaultPoolStartPort,
end: DefaultPoolEndPort,
res: make(map[int]*Res),
start: DefaultPoolStartPort,
end: DefaultPoolEndPort,
res: make(map[int]*Res),
logf: log.Printf,
debugf: func(string, ...interface{}) {},
errorf: func(s string, v ...interface{}) { log.Printf("error: "+s, v...) },
}
// apply opts
@ -85,7 +92,10 @@ func (p *Pool) Allocate(ctxt context.Context, opts ...runner.CommandLineOption)
}
// setup cdp
r.c, err = New(ctxt, WithRunner(r.r))
r.c, err = New(
ctxt, WithRunner(r.r),
WithLogf(p.logf), WithDebugf(p.debugf), WithErrorf(p.errorf),
)
if err != nil {
cancel()
return nil, err
@ -173,3 +183,13 @@ func PortRange(start, end int) PoolOption {
return nil
}
}
// PoolLog is a pool option to set the logging to use for the pool.
func PoolLog(logf, debugf, errorf LogFunc) PoolOption {
return func(p *Pool) error {
p.logf = logf
p.debugf = debugf
p.errorf = errorf
return nil
}
}