2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2021 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 "go.cypherpunks.ru/recfile"
28 "golang.org/x/sys/unix"
31 const LogFdPrefix = "FD:"
44 func (les LEs) Rec() string {
45 b := bytes.NewBuffer(make([]byte, 0, 1<<10))
46 w := recfile.NewWriter(b)
47 _, err := w.RecordStart()
51 _, err = w.WriteFields(recfile.Field{
53 Value: time.Now().UTC().Format(time.RFC3339Nano),
58 for _, le := range les {
59 switch v := le.V.(type) {
60 case int, int8, uint8, int64, uint64:
61 _, err = w.WriteFields(recfile.Field{
63 Value: fmt.Sprintf("%d", v),
66 _, err = w.WriteFields(recfile.Field{
68 Value: fmt.Sprintf("%v", v),
72 _, err = w.WriteFieldMultiline(le.K, v)
75 _, err = w.WriteFields(recfile.Field{
77 Value: fmt.Sprintf("%s", v),
87 func (ctx *Ctx) Log(rec string) {
90 LogFd.WriteString(rec)
94 fdLock, err := os.OpenFile(
96 os.O_CREATE|os.O_WRONLY,
100 fmt.Fprintln(os.Stderr, "Can not open lock for log:", err)
104 fdLockFd := int(fdLock.Fd())
105 err = unix.Flock(fdLockFd, unix.LOCK_EX)
107 fmt.Fprintln(os.Stderr, "Can not acquire lock for log:", err)
110 defer unix.Flock(fdLockFd, unix.LOCK_UN)
111 fd, err := os.OpenFile(
113 os.O_CREATE|os.O_WRONLY|os.O_APPEND,
117 fmt.Fprintln(os.Stderr, "Can not open log:", err)
124 func (ctx *Ctx) LogD(who string, les LEs, msg func(LEs) string) {
128 les = append(LEs{{"Debug", true}, {"Who", who}}, les...)
129 les = append(les, LE{"Msg", msg(les)})
130 fmt.Fprint(os.Stderr, les.Rec())
133 func (ctx *Ctx) LogI(who string, les LEs, msg func(LEs) string) {
134 les = append(LEs{{"Who", who}}, les...)
135 les = append(les, LE{"Msg", msg(les)})
138 fmt.Fprint(os.Stderr, rec)
141 fmt.Fprintln(os.Stderr, ctx.HumanizeRec(rec))
146 func (ctx *Ctx) LogE(who string, les LEs, err error, msg func(LEs) string) {
147 les = append(LEs{{"Err", err.Error()}, {"Who", who}}, les...)
148 les = append(les, LE{"Msg", msg(les)})
151 fmt.Fprint(os.Stderr, rec)
154 fmt.Fprintln(os.Stderr, ctx.HumanizeRec(rec))