Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Add a StdoutTransport #310

Merged
merged 1 commit into from
Mar 21, 2020
Merged

Conversation

mike-burns
Copy link
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

A common pattern is to "log" exceptions and messages to Sentry. It's a
convenient place to collect programmer errors: situations that
absolutely should not happen according to the business logic, but happen
anyway because of constraints not caught by the type system or test
suite.

In debug builds we often have Sentry disabled because we don't want to
clutter it with all the ANRs and simple mistakes of development life.
This can mean that exceptions we are "logging" to Sentry get missed.

Instead we can use a StdoutTransport, logging them to the stdout log:

SentryAndroid.init(this) { options ->
    if (BuildConfig.DEBUG) {
        options.setTransport(StdoutTransport(options.serializer))
    }
}

This will log a message like so:

03-20 18:32:47.623 17385-17436/io.sentry.sample I/System.out: {"breadcrumbs":[],"contexts":{"app":{"app_build":"1","app_identifier":"io.sentry.sample","app_version":"1.0"},"os":{"build":"sdk_google_phone_x86-userdebug 6.0 MASTER 5525988 test-keys","kernel_version":"Linux version 3.10.0+ ([email protected]) (gcc version 4.9 20140827 (prerelease) (GCC) ) #1 SMP PREEMPT Wed Feb 22 08:53:42 PST 2017","name":"Android","rooted":true,"version":"6.0"},"device":{"arch":"x86","archs":["x86"],"battery_level":100.0,"boot_time":"2020-03-17T19:59:39Z","brand":"Android","charging":true,"external_free_storage":534726656,"external_storage_size":534761472,"family":"Android","free_memory":1231368192,"free_storage":346652672,"id":"7db661d77068d2d8","language":"en_US","low_memory":false,"manufacturer":"unknown","memory_size":1588129792,"model":"Android SDK built for x86","model_id":"MASTER","name":"Android SDK built for x86","online":true,"orientation":"portrait","screen_density":3.0,"screen_dpi":480,"screen_height_pixels":1776,"screen_resolution":"1776x1080","screen_width_pixels":1080,"simulator":true,"storage_size":812531712,"timezone":"GMT"}},"dist":"1","event_id":"bb32506411d94d40b042a8a3862f6d43","exception":{"values":[{"module":"java.lang","stacktrace":{"frames":[{"native":false,"filename":"ZygoteInit.java","function":"main","in_app":false,"lineno":616,"module":"com.android.internal.os.ZygoteInit"},{"native":false,"filename":"ZygoteInit.java","function":"run","in_app":false,"lineno":726,"module":"com.android.internal.os.ZygoteInit$MethodAndArgsCaller"},{"native":true,"filename":"Method.java","function":"invoke","in_app":false,"module":"java.lang.reflect.Method"},{"native":false,"filename":"ActivityThread.java","function":"main","in_app":false,"lineno":5417,"module":"android.app.ActivityThread"},{"native":false,"filename":"Looper.java","function":"loop","in_app":false,"lineno":148,"module":"android.os.Looper"},{"native":false,"filename":"Handler.java","function":"dispatchMessage","in_app":false,"lineno":95,"module":"android.os.Handler"},{"native":false,"filename":"Handler.java","function":"handleCallback","in_app":false,"lineno":739,"module":"android.os.Handler"},{"native":false,"filename":"View.java","function":"run","in_app":false,"lineno":21147,"module":"android.view.View$PerformClick"},{"native":false,"filename":"View.java","function":"performClick","in_app":false,"lineno":5198,"module":"android.view.View"},{"native":false,"filename":"lambda","function":"onClick","in_app":true,"module":"io.sentry.sample.-$$Lambda$MainActivity$tVGPRGxxb8SivUa5SKhzp6BuXOI"},{"native":false,"filename":"MainActivity.java","function":"lambda$onCreate$2","in_app":true,"lineno":32,"module":"io.sentry.sample.MainActivity"}]},"thread_id":1,"type":"Exception","value":"java.lang.Exception: java.lang.Exception: Some exception."},{"module":"java.lang","stacktrace":{"frames":[{"native":false,"filename":"ZygoteInit.java","function":"main","in_app":false,"lineno":616,"module":"com.android.internal.os.ZygoteInit"},{"native":false,"filename":"ZygoteInit.java","function":"run","in_app":false,"lineno":726,"module":"com.android.internal.os.ZygoteInit$MethodAndArgsCaller"},{"native":true,"filename":"Method.java","function":"invoke","in_app":false,"module":"java.lang.reflect.Method"},{"native":false,"filename":"ActivityThread.java","function":"main","in_app":false,"lineno":5417,"module":"android.app.ActivityThread"},{"native":false,"filename":"Looper.java","function":"loop","in_app":false,"lineno":148,"module":"android.os.Looper"},{"native":false,"filename":"Handler.java","function":"dispatchMessage","in_app":false,"lineno":95,"module":"android.os.Handler"},{"native":false,"filename":"Handler.java","function":"handleCallback","in_app":false,"lineno":739,"module":"android.os.Handler"},{"native":false,"filename":"View.java","function":"run","in_app":false,"lineno":21147,"module":"android.view.View$PerformClick"},{"native":false,"filename":"View.java","function":"performClick","in_app":false,"lineno":5198,"module":"android.view.View"},{"native":false,"filename":"lambda","function":"onClick","

💡 Motivation and Context

Closes #298, #296. Thanks to marandaneto for the initial implementation.

💚 How did you test it?

Added a unit test. In addition, I QA'ed it by using the sentry-sample app and clicking around (output in the description above).

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • All tests passing

Copy link
Contributor

@marandaneto marandaneto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mike-burns thanks for that :)
I left a small comment but other than that, LGTM.

@codecov-io
Copy link

codecov-io commented Mar 20, 2020

Codecov Report

Merging #310 into master will increase coverage by 0.04%.
The diff coverage is 87.5%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #310      +/-   ##
============================================
+ Coverage     57.49%   57.53%   +0.04%     
- Complexity      587      589       +2     
============================================
  Files            73       74       +1     
  Lines          2790     2800      +10     
  Branches        236      236              
============================================
+ Hits           1604     1611       +7     
- Misses         1069     1072       +3     
  Partials        117      117
Impacted Files Coverage Δ Complexity Δ
...java/io/sentry/core/transport/StdoutTransport.java 87.5% <87.5%> (ø) 2 <2> (?)
...y-core/src/main/java/io/sentry/core/DateUtils.java 50% <0%> (-5.56%) 4% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8a3d35e...3a30cb7. Read the comment docs.

A common pattern is to "log" exceptions and messages to Sentry. It's a
convenient place to collect programmer errors: situations that
absolutely should not happen according to the business logic, but happen
anyway because of constraints not caught by the type system or test
suite.

In debug builds we often have Sentry disabled because we don't want to
clutter it with all the ANRs and simple mistakes of development life.
This can mean that exceptions we are "logging" to Sentry get missed.

Instead we can use a `StdoutTransport`, logging them to the stdout log:

```kotlin
SentryAndroid.init(this) { options ->
    if (BuildConfig.DEBUG) {
        options.setTransport(StdoutTransport(options.serializer))
    }
}
```

This will log a message like so:

```
03-20 18:32:47.623 17385-17436/io.sentry.sample I/System.out: {"breadcrumbs":[],"contexts":{"app":{"app_build":"1","app_identifier":"io.sentry.sample","app_version":"1.0"},"os":{"build":"sdk_google_phone_x86-userdebug 6.0 MASTER 5525988 test-keys","kernel_version":"Linux version 3.10.0+ ([email protected]) (gcc version 4.9 20140827 (prerelease) (GCC) ) getsentry#1 SMP PREEMPT Wed Feb 22 08:53:42 PST 2017","name":"Android","rooted":true,"version":"6.0"},"device":{"arch":"x86","archs":["x86"],"battery_level":100.0,"boot_time":"2020-03-17T19:59:39Z","brand":"Android","charging":true,"external_free_storage":534726656,"external_storage_size":534761472,"family":"Android","free_memory":1231368192,"free_storage":346652672,"id":"7db661d77068d2d8","language":"en_US","low_memory":false,"manufacturer":"unknown","memory_size":1588129792,"model":"Android SDK built for x86","model_id":"MASTER","name":"Android SDK built for x86","online":true,"orientation":"portrait","screen_density":3.0,"screen_dpi":480,"screen_height_pixels":1776,"screen_resolution":"1776x1080","screen_width_pixels":1080,"simulator":true,"storage_size":812531712,"timezone":"GMT"}},"dist":"1","event_id":"bb32506411d94d40b042a8a3862f6d43","exception":{"values":[{"module":"java.lang","stacktrace":{"frames":[{"native":false,"filename":"ZygoteInit.java","function":"main","in_app":false,"lineno":616,"module":"com.android.internal.os.ZygoteInit"},{"native":false,"filename":"ZygoteInit.java","function":"run","in_app":false,"lineno":726,"module":"com.android.internal.os.ZygoteInit$MethodAndArgsCaller"},{"native":true,"filename":"Method.java","function":"invoke","in_app":false,"module":"java.lang.reflect.Method"},{"native":false,"filename":"ActivityThread.java","function":"main","in_app":false,"lineno":5417,"module":"android.app.ActivityThread"},{"native":false,"filename":"Looper.java","function":"loop","in_app":false,"lineno":148,"module":"android.os.Looper"},{"native":false,"filename":"Handler.java","function":"dispatchMessage","in_app":false,"lineno":95,"module":"android.os.Handler"},{"native":false,"filename":"Handler.java","function":"handleCallback","in_app":false,"lineno":739,"module":"android.os.Handler"},{"native":false,"filename":"View.java","function":"run","in_app":false,"lineno":21147,"module":"android.view.View$PerformClick"},{"native":false,"filename":"View.java","function":"performClick","in_app":false,"lineno":5198,"module":"android.view.View"},{"native":false,"filename":"lambda","function":"onClick","in_app":true,"module":"io.sentry.sample.-$$Lambda$MainActivity$tVGPRGxxb8SivUa5SKhzp6BuXOI"},{"native":false,"filename":"MainActivity.java","function":"lambda$onCreate$2","in_app":true,"lineno":32,"module":"io.sentry.sample.MainActivity"}]},"thread_id":1,"type":"Exception","value":"java.lang.Exception: java.lang.Exception: Some exception."},{"module":"java.lang","stacktrace":{"frames":[{"native":false,"filename":"ZygoteInit.java","function":"main","in_app":false,"lineno":616,"module":"com.android.internal.os.ZygoteInit"},{"native":false,"filename":"ZygoteInit.java","function":"run","in_app":false,"lineno":726,"module":"com.android.internal.os.ZygoteInit$MethodAndArgsCaller"},{"native":true,"filename":"Method.java","function":"invoke","in_app":false,"module":"java.lang.reflect.Method"},{"native":false,"filename":"ActivityThread.java","function":"main","in_app":false,"lineno":5417,"module":"android.app.ActivityThread"},{"native":false,"filename":"Looper.java","function":"loop","in_app":false,"lineno":148,"module":"android.os.Looper"},{"native":false,"filename":"Handler.java","function":"dispatchMessage","in_app":false,"lineno":95,"module":"android.os.Handler"},{"native":false,"filename":"Handler.java","function":"handleCallback","in_app":false,"lineno":739,"module":"android.os.Handler"},{"native":false,"filename":"View.java","function":"run","in_app":false,"lineno":21147,"module":"android.view.View$PerformClick"},{"native":false,"filename":"View.java","function":"performClick","in_app":false,"lineno":5198,"module":"android.view.View"},{"native":false,"filename":"lambda","function":"onClick","
```

Closes getsentry#298, getsentry#296. Thanks to marandaneto for the initial implementation.
@marandaneto marandaneto merged commit fcb0fec into getsentry:master Mar 21, 2020
@mike-burns mike-burns deleted the stdout-transport branch March 23, 2020 15:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants