This repository has been archived by the owner on Mar 20, 2024. It is now read-only.
generated from benjivesterby/go-template-repo
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
155 lines (132 loc) · 3.51 KB
/
log.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
// Copyright © 2019 Developer Network, LLC
//
// This file is subject to the terms and conditions defined in
// file 'LICENSE', which is part of this source code package.
package alog
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type log struct {
logger *alog
logtype LogLevel
customtype string
timestamp time.Time
err error
values []interface{}
}
func (l *log) String() (output string) {
err := ""
if l.err != nil {
err = fmt.Sprintf(" | err: %s", l.err.Error())
}
message := ""
strs := l.getmessages(l.values)
if len(strs) > 0 {
message = fmt.Sprintf(" %s", strings.Join(strs, ","))
}
prefix := ""
if len(l.logger.prefix) > 0 {
prefix = fmt.Sprintf("%s ", l.logger.prefix)
}
// Handle the empty message and error section
if err == "" && message == "" {
message = "unable to create log string, empty message and error"
}
output = fmt.Sprintf("%s%s [%s]%s%s",
prefix,
l.timestamp.Format(l.logger.dateformat),
l.Type(),
message,
err,
)
if string(output[len(output)-1]) != "\n" {
output = fmt.Sprintf("%s\n", output)
}
return output
}
// getmessages breaks down the interface values and makes them
// into string messages that can then be represented in the different
// logging systems
func (l *log) getmessages(v []interface{}) (messages []string) {
messages = make([]string, 0)
for _, val := range l.intslice(v) {
messages = append(messages, l.getmessage(val))
}
return messages
}
// intslice takes an interface slice which may contain additional interface
// slices it to a singular interface slice so that it can be properly formatted
// by the logger
func (l *log) intslice(v []interface{}) (flattened []interface{}) {
flattened = make([]interface{}, 0)
for _, value := range v {
switch x := value.(type) {
case string:
flattened = append(flattened, x)
case []string:
for _, s := range x {
flattened = append(flattened, s)
}
case []interface{}:
flattened = append(flattened, l.intslice(x)...)
default:
flattened = append(flattened, l.getmessage(x))
}
}
return flattened
}
// getmessage type switches the interface coming in to get a proper
// string value from each type based on the type selection
func (l *log) getmessage(v interface{}) string {
switch field := v.(type) {
case string:
return field
case fmt.Stringer:
return field.String()
default:
return fmt.Sprintf("%v", field)
}
}
// MarshalJSON is used by the json marshaller to properly break
// down a log into a json struct for simpler parsing
func (l *log) MarshalJSON() ([]byte, error) {
var err *string
if l.err != nil {
e := l.err.Error()
err = &e
}
var prefix *string
if len(l.logger.prefix) > 0 {
prefix = &l.logger.prefix
}
// Setup a new flattened struct for json dumps of the logs
output := &struct {
Prefix *string `json:"prefix,omitempty"`
LogType string `json:"type"`
Timestamp string `json:"timestamp"`
Error *string `json:"error,omitempty"`
Messages []string `json:"messages"`
}{
prefix,
l.Type(),
l.timestamp.Format(l.logger.dateformat),
err,
l.getmessages(l.values),
}
return json.Marshal(output)
}
// Type returns the type of the log for parsing or displaying
func (l *log) Type() (t string) {
if l.logtype&CUSTOM > 0 && l.customtype != "" {
return strings.ToUpper(l.customtype)
}
return l.logtype.String()
}
// Validate checks to see if a log is valid meaning it either has a
// message or an error attached to it
func (l *log) Validate() bool {
return l.err != nil || len(l.getmessages(l.values)) > 0
}