func (d *Deduper) Log(keyvals ...interface{}) error {
	line, err := encode(keyvals...)
	if err != nil {
		return err
	}

	d.mtx.RLock()
	last, ok := d.seen[line]
	d.mtx.RUnlock()

	if ok && time.Since(last) < d.repeat {
		return nil
	}

	d.mtx.Lock()
	if len(d.seen) < maxEntries {
		d.seen[line] = time.Now()
	}
	d.mtx.Unlock()

	return d.next.Log(keyvals...)
}
func (d *Deduper) Log(keyvals ...interface{}) error {
	line, err := encode(keyvals...)
	if err != nil {
		return err
	}

	d.mtx.RLock()
	last, ok := d.seen[line]
	d.mtx.RUnlock()

	if ok && time.Since(last) < d.repeat {
		return nil
	}

	d.mtx.Lock()
	if len(d.seen) < maxEntries {
		d.seen[line] = time.Now()
	}
	d.mtx.Unlock()

	return d.next.Log(keyvals...)
}
func ( d * Deduper ) Log ( keyvals ... interface { } ) error { line , err := encode ( keyvals ... ) if err != nil { return err } d . mtx . RLock ( ) last , ok := d . seen [ line ] d . mtx . RUnlock ( ) if ok && time . Since ( last ) < d . repeat { return nil } d . mtx . Lock ( ) if len ( d . seen ) < maxEntries { d . seen [ line ] = time . Now ( ) } d . mtx . Unlock ( ) return d . next . Log ( keyvals ... ) }
// Log implements log.Logger.
Log implements log . Logger .