forked from apsdehal/go-logger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
work.go
160 lines (146 loc) Β· 4.44 KB
/
work.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// COPYRIGHT (c) 2019-2021 SILVANO ZAMPARDI, ALL RIGHTS RESERVED.
// The license for these sources can be found in the LICENSE file in the root directory of this source tree.
package log
import (
"bytes"
"fmt"
"io"
"log"
"os"
"path"
"runtime"
"strings"
"sync/atomic"
"time"
"github.com/szampardi/msg/ansi"
)
// Worker class, Worker is a log object used to log messages and Color specifies
// if colored output is to be produced
type worker struct {
Minion *log.Logger
Color bool
format string
timeFormat string
level Lvl
}
//NewWorker Returns an instance of worker class, prefix is the string attached to every log,
// flag determine the log params, color parameters verifies whether we need colored outputs or not
func newWorker(prefix string, format, timeformat string, flag int, color bool, out io.Writer, lvl Lvl) *worker {
if format == "" {
format = Formats[PlainFormat]._String
}
if timeformat == "" {
timeformat = time.RFC3339
}
if out == nil {
out = os.Stdout
}
return &worker{
Minion: log.New(out, prefix, flag),
Color: color,
format: format,
timeFormat: timeformat,
level: lvl,
}
}
// New Returns a new instance of logger class, module is the specific module for which we are logging
// , color defines whether the output is to be colored or not, out is instance of type io.Writer defaults
// to os.Stderr
func New(format, timeformat string, args ...interface{}) (Logger, error) {
var module string = "msg"
var color bool = true
var out io.Writer = os.Stderr
var level Lvl = LDefault
for _, arg := range args {
switch t := arg.(type) {
case string:
module = t
case bool:
color = t
case io.Writer:
out = t
case Lvl:
level = t
default:
return *defaultLogger, fmt.Errorf("%s:\t%s", "invalid argument", t)
}
}
//newWorker.setLogLevel(level)
return Logger{
Module: module,
worker: newWorker("", format, timeformat, 0, color, out, level),
}, nil
}
// Logger class that is an interface to user to log messages, Module is the module for which we are testing
// worker is variable of Worker class that is used in bottom layers to log the message
type Logger struct {
Module string
worker *worker
}
// Output ...
func (l *Logger) Output(calldepth int, s string) error {
return l.worker.Minion.Output(calldepth, s)
}
// SetOutput ...
func (l *Logger) SetOutput(w io.Writer) {
l.worker.Minion.SetOutput(w)
}
//Log The log commnand is the function available to user to log message, lvl specifies
// the degree of the message the user wants to log, message is the info user wants to log
func (l *Logger) Log(lvl Lvl, message string) {
l.logInternal(lvl, message, 2)
}
//Log The log commnand is the function available to user to log message, lvl specifies
// the degree of the message the user wants to log, message is the info user wants to log
func Log(lvl Lvl, message string) {
defaultLogger.logInternal(lvl, message, 2)
}
func (l *Logger) logInternal(lvl Lvl, message string, pos int) {
//var formatString string = "#%d %s [%s] %s:%d βΆ %.3s %s"
_, filename, line, _ := runtime.Caller(pos)
filename = path.Base(filename)
info := &info{
ID: atomic.AddUint32(&logNo, 1),
Time: time.Now().Format(l.worker.timeFormat),
Module: l.Module,
Filename: filename,
Line: line,
Level: lvl,
Message: message,
//format: formatString,
}
l.worker.log(lvl, 2, info)
}
// Log is Function of Worker class to log a string based on level
func (w *worker) log(level Lvl, calldepth int, info *info) error {
if w.level < level {
return nil
}
if w.Color {
buf := &bytes.Buffer{}
buf.Write(Levels[level].escapedBytes)
buf.Write([]byte(info.output(w.format)))
buf.Write(ansi.Controls["Reset"].Bytes)
return w.Minion.Output(calldepth+1, buf.String())
}
return w.Minion.Output(calldepth+1, info.output(w.format))
}
// Output Returns a proper string to be outputted for a particular info
func (r *info) output(format string) string {
msg := fmt.Sprintf(
format,
r.ID, // %[1] // %{id}
r.Time, // %[2] // %{time[:fmt]}
r.Module, // %[3] // %{module}
r.Filename, // %[4] // %{filename}
r.Line, // %[5] // %{line}
Levels[r.Level].Str, // %[6] // %{level}
r.Message, // %[7] // %{message}
Levels[r.Level].emoji, // %[8] // %{emoji}
)
// Ignore printf errors if len(args) > len(verbs)
if i := strings.LastIndex(msg, "%!(EXTRA"); i != -1 {
return msg[:i]
}
return msg
}