func (log *Logger) WithCountLimit(batch, limit int64) *Logger {
	if batch <= 0 {
		panic("logger.WithCountLimit: batch must be positive")
	}
	if limit < 0 {
		panic("logger.WithCountLimit: negative limit")
	}
	clone := *log
	clone.attr.CountLimiter = func(record *iface.Record) bool {
		loc := locator{
			File: record.File,
			Line: record.Line,
		}
		n := log.countMap[loc]
		log.countMap[loc]++
		return n%batch < limit
	}
	return &clone
}
WithCountLimit returns a new Logger that is a shallow copy of the Logger.
With the new Logger, the count of logs it outputs will be limited as long as
the LimitByCount flag is NOT disabled.

The batch MUST be positive and the limit must NOT be negative. As a result,
limit logs will be output every batch logs.

THINK TWICE before you decide to limit the output of logs, you may miss logs
which you need.
package logger
import (
	"fmt"
	"time"
	"github.com/gxlog/gxlog/iface"
)
const mapInitCap = 256
type Dynamic func(key interface{}) interface{}
type dynamicContext struct {
	Key   interface{}
	Value Dynamic
}
type locator struct {
	File string
	Line int
}
type copyOnWrite struct {
	Prefix          string
	Contexts        []iface.Context
	DynamicContexts []dynamicContext
	Marked          bool
	CountLimiter    Filter
	TimeLimiter     Filter
}
func (log *Logger) WithPrefix(prefix string) *Logger {
	clone := *log
	clone.attr.Prefix = prefix
	return &clone
}
func (log *Logger) WithContext(kvs ...interface{}) *Logger {
	clone := *log
	clone.attr.Contexts, clone.attr.DynamicContexts =
		appendContexts(clone.attr.Contexts, clone.attr.DynamicContexts, kvs)
	return &clone
}
func (log *Logger) WithMark(ok bool) *Logger {
	clone := *log
	clone.attr.Marked = ok
	return &clone
}