]> Sergey Matveev's repositories - btrtrc.git/blob - logonce/logonce.go
Drop support for go 1.20
[btrtrc.git] / logonce / logonce.go
1 // Package logonce implements an io.Writer facade that only performs distinct
2 // writes. This can be used by log.Loggers as they're guaranteed to make a
3 // single Write method call for each message. This is useful for loggers that
4 // print useful information about unexpected conditions that aren't fatal in
5 // code.
6 package logonce
7
8 import (
9         "io"
10         "log"
11         "os"
12 )
13
14 // A default logger similar to the default logger in the log package.
15 var Stderr *log.Logger
16
17 func init() {
18         // This should emulate the default logger in the log package where
19         // possible. No time flag so that messages don't differ by time. Code
20         // debug information is useful.
21         Stderr = log.New(Writer(os.Stderr), "logonce: ", log.Lshortfile)
22 }
23
24 type writer struct {
25         w      io.Writer
26         writes map[string]struct{}
27 }
28
29 func (w writer) Write(p []byte) (n int, err error) {
30         s := string(p)
31         if _, ok := w.writes[s]; ok {
32                 return
33         }
34         n, err = w.w.Write(p)
35         if n != len(s) {
36                 s = string(p[:n])
37         }
38         w.writes[s] = struct{}{}
39         return
40 }
41
42 func Writer(w io.Writer) io.Writer {
43         return writer{
44                 w:      w,
45                 writes: make(map[string]struct{}),
46         }
47 }