2 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
3 Copyright (C) 2016-2020 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 "golang.org/x/sys/unix"
32 type SDS map[string]interface{}
34 func sdFmt(who string, sds SDS) string {
35 keys := make([]string, 0, len(sds))
36 for k, _ := range sds {
37 keys = append(keys, k)
40 result := make([]string, 0, 1+len(keys))
41 result = append(result, "["+who)
42 for _, k := range keys {
44 switch v := sds[k].(type) {
45 case int, int8, uint8, int64, uint64:
46 value = fmt.Sprintf("%d", v)
48 value = fmt.Sprintf("%s", v)
50 result = append(result, fmt.Sprintf(`%s="%s"`, k, value))
52 return strings.Join(result, " ") + "]"
55 func msgFmt(level LogLevel, who string, sds SDS, msg string) string {
56 result := fmt.Sprintf(
59 time.Now().UTC().Format(time.RFC3339Nano),
68 func (ctx *Ctx) Log(msg string) {
69 fdLock, err := os.OpenFile(
71 os.O_CREATE|os.O_WRONLY,
75 fmt.Fprintln(os.Stderr, "Can not open lock for log:", err)
79 fdLockFd := int(fdLock.Fd())
80 err = unix.Flock(fdLockFd, unix.LOCK_EX)
82 fmt.Fprintln(os.Stderr, "Can not acquire lock for log:", err)
85 defer unix.Flock(fdLockFd, unix.LOCK_UN)
86 fd, err := os.OpenFile(
88 os.O_CREATE|os.O_WRONLY|os.O_APPEND,
92 fmt.Fprintln(os.Stderr, "Can not open log:", err)
95 fd.WriteString(msg) // #nosec G104
96 fd.Close() // #nosec G104
99 func (ctx *Ctx) LogD(who string, sds SDS, msg string) {
103 fmt.Fprint(os.Stderr, msgFmt(LogLevel("D"), who, sds, msg))
106 func (ctx *Ctx) LogI(who string, sds SDS, msg string) {
107 msg = msgFmt(LogLevel("I"), who, sds, msg)
109 fmt.Fprintln(os.Stderr, ctx.Humanize(msg))
114 func (ctx *Ctx) LogE(who string, sds SDS, err error, msg string) {
115 sds["err"] = err.Error()
116 msg = msgFmt(LogLevel("E"), who, sds, msg)
120 fmt.Fprintln(os.Stderr, ctx.Humanize(msg))
124 func SdsAdd(sds, add SDS) SDS {
126 for k, v := range sds {
129 for k, v := range add {