Skip to content

Commit 4c2ee8c

Browse files
authored
Merge pull request #115 from rollbar/pawel/move_log_to_client
adding log capability to client
2 parents 545025c + 5fbbe46 commit 4c2ee8c

File tree

3 files changed

+280
-42
lines changed

3 files changed

+280
-42
lines changed

client.go

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,153 @@ func NewSync(token, environment, codeVersion, serverHost, serverRoot string) *Cl
8080
}
8181
}
8282

83+
// Log reports an item with the given level. This function recognizes arguments with the following types:
84+
//
85+
// *http.Request
86+
// error
87+
// string
88+
// map[string]interface{}
89+
// int
90+
// context.Context
91+
//
92+
// The string and error types are mutually exclusive.
93+
// If an error is present then a stack trace is captured. If an int is also present then we skip
94+
// that number of stack frames. If the map is present it is used as extra custom data in the
95+
// item. If a string is present without an error, then we log a message without a stack
96+
// trace. If a request is present we extract as much relevant information from it as we can. If
97+
// a context is present, it is applied to downstream operations.
98+
func (c *Client) Log(level string, interfaces ...interface{}) {
99+
var r *http.Request
100+
var err error
101+
var skip int
102+
skipSet := false
103+
var extras map[string]interface{}
104+
var msg string
105+
ctx := context.TODO()
106+
for _, ival := range interfaces {
107+
switch val := ival.(type) {
108+
case *http.Request:
109+
r = val
110+
case error:
111+
err = val
112+
case int:
113+
skip = val
114+
skipSet = true
115+
case string:
116+
msg = val
117+
case map[string]interface{}:
118+
extras = val
119+
case context.Context:
120+
ctx = val
121+
default:
122+
rollbarError(c.Transport.(*AsyncTransport).Logger, "Unknown input type: %T", val)
123+
}
124+
}
125+
if !skipSet {
126+
skip = 2
127+
}
128+
if err != nil {
129+
if r == nil {
130+
c.ErrorWithStackSkipWithExtrasAndContext(ctx, level, err, skip, extras)
131+
} else {
132+
c.RequestErrorWithStackSkipWithExtrasAndContext(ctx, level, r, err, skip, extras)
133+
}
134+
} else {
135+
if r == nil {
136+
c.MessageWithExtrasAndContext(ctx, level, msg, extras)
137+
} else {
138+
c.RequestMessageWithExtrasAndContext(ctx, level, r, msg, extras)
139+
}
140+
}
141+
}
142+
143+
// -- Reporting
144+
145+
// Critical reports an item with level `critical`. This function recognizes arguments with the following types:
146+
//
147+
// *http.Request
148+
// error
149+
// string
150+
// map[string]interface{}
151+
// int
152+
//
153+
// The string and error types are mutually exclusive.
154+
// If an error is present then a stack trace is captured. If an int is also present then we skip
155+
// that number of stack frames. If the map is present it is used as extra custom data in the
156+
// item. If a string is present without an error, then we log a message without a stack
157+
// trace. If a request is present we extract as much relevant information from it as we can.
158+
func (c *Client) Critical(interfaces ...interface{}) {
159+
c.Log(CRIT, interfaces...)
160+
}
161+
162+
// Error reports an item with level `error`. This function recognizes arguments with the following types:
163+
//
164+
// *http.Request
165+
// error
166+
// string
167+
// map[string]interface{}
168+
// int
169+
//
170+
// The string and error types are mutually exclusive.
171+
// If an error is present then a stack trace is captured. If an int is also present then we skip
172+
// that number of stack frames. If the map is present it is used as extra custom data in the
173+
// item. If a string is present without an error, then we log a message without a stack
174+
// trace. If a request is present we extract as much relevant information from it as we can.
175+
func (c *Client) Error(interfaces ...interface{}) {
176+
c.Log(ERR, interfaces...)
177+
}
178+
179+
// Warning reports an item with level `warning`. This function recognizes arguments with the following types:
180+
//
181+
// *http.Request
182+
// error
183+
// string
184+
// map[string]interface{}
185+
// int
186+
//
187+
// The string and error types are mutually exclusive.
188+
// If an error is present then a stack trace is captured. If an int is also present then we skip
189+
// that number of stack frames. If the map is present it is used as extra custom data in the
190+
// item. If a string is present without an error, then we log a message without a stack
191+
// trace. If a request is present we extract as much relevant information from it as we can.
192+
func (c *Client) Warning(interfaces ...interface{}) {
193+
c.Log(WARN, interfaces...)
194+
}
195+
196+
// Info reports an item with level `info`. This function recognizes arguments with the following types:
197+
//
198+
// *http.Request
199+
// error
200+
// string
201+
// map[string]interface{}
202+
// int
203+
//
204+
// The string and error types are mutually exclusive.
205+
// If an error is present then a stack trace is captured. If an int is also present then we skip
206+
// that number of stack frames. If the map is present it is used as extra custom data in the
207+
// item. If a string is present without an error, then we log a message without a stack
208+
// trace. If a request is present we extract as much relevant information from it as we can.
209+
func (c *Client) Info(interfaces ...interface{}) {
210+
c.Log(INFO, interfaces...)
211+
}
212+
213+
// Debug reports an item with level `debug`. This function recognizes arguments with the following types:
214+
//
215+
// *http.Request
216+
// error
217+
// string
218+
// map[string]interface{}
219+
// int
220+
//
221+
// The string and error types are mutually exclusive.
222+
// If an error is present then a stack trace is captured. If an int is also present then we skip
223+
// that number of stack frames. If the map is present it is used as extra custom data in the
224+
// item. If a string is present without an error, then we log a message without a stack
225+
// trace. If a request is present we extract as much relevant information from it as we can.
226+
func (c *Client) Debug(interfaces ...interface{}) {
227+
c.Log(DEBUG, interfaces...)
228+
}
229+
83230
// CaptureTelemetryEvent sets the user-specified telemetry event
84231
func (c *Client) CaptureTelemetryEvent(eventType, eventlevel string, eventData map[string]interface{}) {
85232
data := map[string]interface{}{}

client_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,138 @@ func TestLogPanic(t *testing.T) {
7272
client.Close()
7373
}
7474

75+
func TestLogError(t *testing.T) {
76+
client := testClient()
77+
client.Error(errors.New("logged error"))
78+
if transport, ok := client.Transport.(*TestTransport); ok {
79+
if transport.WaitCalled {
80+
t.Error("Wait called unexpectedly")
81+
}
82+
body := transport.Body
83+
if body["data"] == nil {
84+
t.Error("body should have data")
85+
}
86+
data := body["data"].(map[string]interface{})
87+
dataError := errorFromData(data)
88+
if dataError["message"] != "logged error" {
89+
t.Error("data should have correct error message")
90+
}
91+
} else {
92+
t.Fail()
93+
}
94+
client.Close()
95+
}
96+
97+
func TestLogCriticalLevel(t *testing.T) {
98+
client := testClient()
99+
client.Critical(errors.New("logged error"))
100+
if transport, ok := client.Transport.(*TestTransport); ok {
101+
if transport.WaitCalled {
102+
t.Error("Wait called unexpectedly")
103+
}
104+
body := transport.Body
105+
if body["data"] == nil {
106+
t.Error("body should have data")
107+
}
108+
data := body["data"].(map[string]interface{})
109+
110+
if data["level"] != CRIT {
111+
t.Error("data should have correct level")
112+
}
113+
} else {
114+
t.Fail()
115+
}
116+
client.Close()
117+
}
118+
119+
func TestLogErrorLevel(t *testing.T) {
120+
client := testClient()
121+
client.Error(errors.New("logged error"))
122+
if transport, ok := client.Transport.(*TestTransport); ok {
123+
if transport.WaitCalled {
124+
t.Error("Wait called unexpectedly")
125+
}
126+
body := transport.Body
127+
if body["data"] == nil {
128+
t.Error("body should have data")
129+
}
130+
data := body["data"].(map[string]interface{})
131+
132+
if data["level"] != ERR {
133+
t.Error("data should have correct level")
134+
}
135+
} else {
136+
t.Fail()
137+
}
138+
client.Close()
139+
}
140+
141+
func TestLogWarningLevel(t *testing.T) {
142+
client := testClient()
143+
client.Warning(errors.New("logged error"))
144+
if transport, ok := client.Transport.(*TestTransport); ok {
145+
if transport.WaitCalled {
146+
t.Error("Wait called unexpectedly")
147+
}
148+
body := transport.Body
149+
if body["data"] == nil {
150+
t.Error("body should have data")
151+
}
152+
data := body["data"].(map[string]interface{})
153+
154+
if data["level"] != WARN {
155+
t.Error("data should have correct level")
156+
}
157+
} else {
158+
t.Fail()
159+
}
160+
client.Close()
161+
}
162+
163+
func TestLogInfoLevel(t *testing.T) {
164+
client := testClient()
165+
client.Info("some message")
166+
if transport, ok := client.Transport.(*TestTransport); ok {
167+
if transport.WaitCalled {
168+
t.Error("Wait called unexpectedly")
169+
}
170+
body := transport.Body
171+
if body["data"] == nil {
172+
t.Error("body should have data")
173+
}
174+
data := body["data"].(map[string]interface{})
175+
176+
if data["level"] != INFO {
177+
t.Error("data should have correct level")
178+
}
179+
} else {
180+
t.Fail()
181+
}
182+
client.Close()
183+
}
184+
185+
func TestLogDebugLevel(t *testing.T) {
186+
client := testClient()
187+
client.Debug("some message")
188+
if transport, ok := client.Transport.(*TestTransport); ok {
189+
if transport.WaitCalled {
190+
t.Error("Wait called unexpectedly")
191+
}
192+
body := transport.Body
193+
if body["data"] == nil {
194+
t.Error("body should have data")
195+
}
196+
data := body["data"].(map[string]interface{})
197+
198+
if data["level"] != DEBUG {
199+
t.Error("data should have correct level")
200+
}
201+
} else {
202+
t.Fail()
203+
}
204+
client.Close()
205+
}
206+
75207
func TestWrap(t *testing.T) {
76208
client := testClient()
77209
err := errors.New("bork")

rollbar.go

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -463,48 +463,7 @@ func Debug(interfaces ...interface{}) {
463463
// trace. If a request is present we extract as much relevant information from it as we can. If
464464
// a context is present, it is applied to downstream operations.
465465
func Log(level string, interfaces ...interface{}) {
466-
var r *http.Request
467-
var err error
468-
var skip int
469-
skipSet := false
470-
var extras map[string]interface{}
471-
var msg string
472-
ctx := context.TODO()
473-
for _, ival := range interfaces {
474-
switch val := ival.(type) {
475-
case *http.Request:
476-
r = val
477-
case error:
478-
err = val
479-
case int:
480-
skip = val
481-
skipSet = true
482-
case string:
483-
msg = val
484-
case map[string]interface{}:
485-
extras = val
486-
case context.Context:
487-
ctx = val
488-
default:
489-
rollbarError(std.Transport.(*AsyncTransport).Logger, "Unknown input type: %T", val)
490-
}
491-
}
492-
if !skipSet {
493-
skip = 2
494-
}
495-
if err != nil {
496-
if r == nil {
497-
std.ErrorWithStackSkipWithExtrasAndContext(ctx, level, err, skip, extras)
498-
} else {
499-
std.RequestErrorWithStackSkipWithExtrasAndContext(ctx, level, r, err, skip, extras)
500-
}
501-
} else {
502-
if r == nil {
503-
std.MessageWithExtrasAndContext(ctx, level, msg, extras)
504-
} else {
505-
std.RequestMessageWithExtrasAndContext(ctx, level, r, msg, extras)
506-
}
507-
}
466+
std.Log(level, interfaces...)
508467
}
509468

510469
// -- Error reporting

0 commit comments

Comments
 (0)