func (b *Backend) Logger() log.Logger {
	if b.logger != nil {
		return b.logger
	}
	return logformat.NewVaultLoggerWithWriter(ioutil.Discard, log.LevelOff)
}
Logger can be used to get the logger. If no logger has been set,
the logs will be discarded.
package framework
import (
	"fmt"
	"io/ioutil"
	"regexp"
	"sort"
	"strings"
	"sync"
	"time"
	log "github.com/mgutz/logxi/v1"
	"github.com/hashicorp/go-multierror"
	"github.com/hashicorp/vault/helper/errutil"
	"github.com/hashicorp/vault/helper/logformat"
	"github.com/hashicorp/vault/logical"
)
type Backend struct {
	Help string
	Paths        []*Path
	PathsSpecial *logical.Paths
	Secrets []*Secret
	PeriodicFunc periodicFunc
	WALRollback       WALRollbackFunc
	WALRollbackMinAge time.Duration
	Clean CleanupFunc
	AuthRenew OperationFunc
	logger  log.Logger
	system  logical.SystemView
	once    sync.Once
	pathsRe []*regexp.Regexp
}
type periodicFunc func(*logical.Request) error
type OperationFunc func(*logical.Request, *FieldData) (*logical.Response, error)
type WALRollbackFunc func(*logical.Request, string, interface{}) error
type CleanupFunc func()
func (b *Backend) HandleExistenceCheck(req *logical.Request) (checkFound bool, exists bool, err error) {
	b.once.Do(b.init)
	switch req.Operation {
	case logical.CreateOperation:
	case logical.UpdateOperation:
	default:
		return false, false, fmt.Errorf("incorrect operation type %v for an existence check", req.Operation)
	}
	path, captures := b.route(req.Path)
	if path == nil {
		return false, false, logical.ErrUnsupportedPath
	}
	if path.ExistenceCheck == nil {
		return false, false, nil
	}
	checkFound = true
	raw := make(map[string]interface{}, len(path.Fields))
	for k, v := range req.Data {
		raw[k] = v
	}
	for k, v := range captures {
		raw[k] = v
	}
	fd := FieldData{
		Raw:    raw,
		Schema: path.Fields}
	err = fd.Validate()
	if err != nil {
		return false, false, errutil.UserError{Err: err.Error()}
	}
	exists, err = path.ExistenceCheck(req, &fd)
	return
}
func (b *Backend) HandleRequest(req *logical.Request) (*logical.Response, error) {
	b.once.Do(b.init)
	switch req.Operation {
	case logical.RenewOperation:
		fallthrough
	case logical.RevokeOperation:
		return b.handleRevokeRenew(req)
	case logical.RollbackOperation:
		return b.handleRollback(req)
	}
	if req.Path == "" && req.Operation == logical.HelpOperation {
		return b.handleRootHelp()
	}
	path, captures := b.route(req.Path)
	if path == nil {
		return nil, logical.ErrUnsupportedPath
	}
	raw := make(map[string]interface{}, len(path.Fields))
	for k, v := range req.Data {
		raw[k] = v
	}
	for k, v := range captures {
		raw[k] = v
	}
	var callback OperationFunc
	var ok bool
	if path.Callbacks != nil {
		callback, ok = path.Callbacks[req.Operation]
	}
	if !ok {
		if req.Operation == logical.HelpOperation {
			callback = path.helpCallback
			ok = true
		}
	}
	if !ok {
		return nil, logical.ErrUnsupportedOperation
	}
	fd := FieldData{
		Raw:    raw,
		Schema: path.Fields}
	if req.Operation != logical.HelpOperation {
		err := fd.Validate()
		if err != nil {
			return nil, err
		}
	}
	return callback(req, &fd)
}
func (b *Backend) SpecialPaths() *logical.Paths {
	return b.PathsSpecial
}
func (b *Backend) Setup(config *logical.BackendConfig) (logical.Backend, error) {
	b.logger = config.Logger
	b.system = config.System
	return b, nil
}
func (b *Backend) Cleanup() {
	if b.Clean != nil {
		b.Clean()
	}
}