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

Commit

Permalink
Add a StdoutTransport
Browse files Browse the repository at this point in the history
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+ (lfy@lfy0.mtv.corp.google.com) (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","
```

Closes #298, #296. Thanks to marandaneto for the initial implementation.
  • Loading branch information
mike-burns committed Mar 20, 2020
1 parent 8a3d35e commit d68e2ef
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.sentry.core.transport;

import io.sentry.core.ISerializer;
import io.sentry.core.SentryEvent;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;

public final class StdoutTransport implements ITransport {
private final ISerializer serializer;

public StdoutTransport(final ISerializer serializer) {
this.serializer = serializer;
}

@Override
public TransportResult send(SentryEvent event) throws IOException {
Writer outputStreamWriter = new OutputStreamWriter(System.out, Charset.defaultCharset());
PrintWriter printWriter = new PrintWriter(outputStreamWriter);

serializer.serialize(event, printWriter);

return TransportResult.success();
}

@Override
public void close() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.sentry.core.transport

import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.verify
import io.sentry.core.ISerializer
import io.sentry.core.SentryEvent
import io.sentry.core.SentryOptions
import org.junit.Test
import kotlin.test.assertTrue

class StdoutTransportTest {
private class Fixture {
val serializer = mock<ISerializer>()

fun getSUT(): ITransport {
val options = SentryOptions()
options.setSerializer(serializer)

return StdoutTransport(serializer)
}
}

private val fixture = Fixture()

@Test
fun `test serializes event`() {
val transport = fixture.getSUT()
val event = SentryEvent()

val result = transport.send(event)

verify(fixture.serializer).serialize(eq(event), any())
assertTrue(result.isSuccess)
}
}

0 comments on commit d68e2ef

Please sign in to comment.