func NewClient(servers []string, logger log.Logger, options ...Option) (Client, error) {
	defaultEventHandler := func(event zk.Event) {
		logger.Log("eventtype", event.Type.String(), "server", event.Server, "state", event.State.String(), "err", event.Err)
	}
	config := clientConfig{
		acl:            DefaultACL,
		connectTimeout: DefaultConnectTimeout,
		sessionTimeout: DefaultSessionTimeout,
		eventHandler:   defaultEventHandler,
		logger:         logger,
	}
	for _, option := range options {
		if err := option(&config); err != nil {
			return nil, err
		}
	}
	dialer := func(network, address string, _ time.Duration) (net.Conn, error) {
		return net.DialTimeout(network, address, config.connectTimeout)
	}
	conn, eventc, err := zk.Connect(servers, config.sessionTimeout, withLogger(logger), zk.WithDialer(dialer))
	if err != nil {
		return nil, err
	}
	if len(config.credentials) > 0 {
		err = conn.AddAuth("digest", config.credentials)
		if err != nil {
			return nil, err
		}
	}
	c := &client{conn, config, true, make(chan struct{})}
	go func() {
		for {
			select {
			case event := <-eventc:
				config.eventHandler(event)
			case <-c.quit:
				return
			}
		}
	}()
	return c, nil
}
NewClient returns a ZooKeeper client with a connection to the server cluster.
It will return an error if the server cluster cannot be resolved.
package zk
import (
	"errors"
	"net"
	"strings"
	"time"
	"github.com/samuel/go-zookeeper/zk"
	"github.com/go-kit/kit/log"
)
var (
	DefaultACL            = zk.WorldACL(zk.PermAll)
	ErrInvalidCredentials = errors.New("invalid credentials provided")
	ErrClientClosed       = errors.New("client service closed")
	ErrNotRegistered      = errors.New("not registered")
	ErrNodeNotFound       = errors.New("node not found")
)
const (
	DefaultConnectTimeout = 2 * time.Second
	DefaultSessionTimeout = 5 * time.Second
)
type Client interface {
	GetEntries(path string) ([]string, <-chan zk.Event, error)
	CreateParentNodes(path string) error
	Register(s *Service) error
	Deregister(s *Service) error
	Stop()
}
type clientConfig struct {
	logger          log.Logger
	acl             []zk.ACL
	credentials     []byte
	connectTimeout  time.Duration
	sessionTimeout  time.Duration
	rootNodePayload [][]byte
	eventHandler    func(zk.Event)
}
type Option func(*clientConfig) error
type client struct {
	*zk.Conn
	clientConfig
	active bool
	quit   chan struct{}
}
func ACL(acl []zk.ACL) Option {
	return func(c *clientConfig) error {
		c.acl = acl
		return nil
	}
}
func Credentials(user, pass string) Option {
	return func(c *clientConfig) error {
		if user == "" || pass == "" {
			return ErrInvalidCredentials
		}
		c.credentials = []byte(user + ":" + pass)
		return nil
	}
}
func ConnectTimeout(t time.Duration) Option {
	return func(c *clientConfig) error {
		if t.Seconds() < 1 {
			return errors.New("invalid connect timeout (minimum value is 1 second)")
		}
		c.connectTimeout = t
		return nil
	}
}
func SessionTimeout(t time.Duration) Option {
	return func(c *clientConfig) error {
		if t.Seconds() < 1 {
			return errors.New("invalid session timeout (minimum value is 1 second)")
		}
		c.sessionTimeout = t
		return nil
	}
}
func Payload(payload [][]byte) Option {
	return func(c *clientConfig) error {
		c.rootNodePayload = payload
		return nil
	}
}
func EventHandler(handler func(zk.Event)) Option {
	return func(c *clientConfig) error {
		c.eventHandler = handler
		return nil
	}
}