Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sentry-android-ndk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_library(sentry-android SHARED src/main/jni/sentry.c)
# make sure that we build it as a shared lib instead of a static lib
set(BUILD_SHARED_LIBS ON)
set(SENTRY_BUILD_SHARED_LIBS ON)
set(SENTRY_BACKEND "breakpad")

# Adding sentry-native submodule subdirectory
add_subdirectory(${SENTRY_NATIVE_SRC} sentry_build)
Expand Down
1 change: 1 addition & 0 deletions sentry-samples/sentry-samples-android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_library(native-sample SHARED src/main/cpp/native-sample.cpp)
# make sure that we build it as a shared lib instead of a static lib
set(BUILD_SHARED_LIBS ON)
set(SENTRY_BUILD_SHARED_LIBS ON)
set(SENTRY_BACKEND "breakpad")

add_subdirectory(../../sentry-android-ndk/${SENTRY_NATIVE_SRC} sentry_build)

Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/Attachment.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public final class Attachment {
private final @NotNull String filename;
private final @NotNull String contentType;
private final boolean addToTransactions;
private final @NotNull String attachmentType = "event.attachment";

/**
* We could use Files.probeContentType(path) to determine the content type of the filename. This
Expand Down Expand Up @@ -187,4 +188,8 @@ public Attachment(
boolean isAddToTransactions() {
return addToTransactions;
}

public @NotNull String getAttachmentType() {
return attachmentType;
}
}
193 changes: 101 additions & 92 deletions sentry/src/main/java/io/sentry/OutboxSender.java
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
package io.sentry;

import static io.sentry.SentryLevel.ERROR;
//import static io.sentry.SentryLevel.ERROR;
import static io.sentry.cache.EnvelopeCache.PREFIX_CURRENT_SESSION_FILE;

import io.sentry.hints.Flushable;
import io.sentry.hints.Resettable;
//import io.sentry.hints.Resettable;
import io.sentry.hints.Retryable;
import io.sentry.hints.SubmissionResult;
//import io.sentry.hints.SubmissionResult;
import io.sentry.util.CollectionUtils;
import io.sentry.util.LogUtils;
import io.sentry.util.Objects;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
//import java.io.BufferedReader;
//import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
//import java.io.InputStreamReader;
//import java.io.Reader;
//import java.nio.charset.Charset;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
public final class OutboxSender extends DirectoryProcessor implements IEnvelopeSender {

@SuppressWarnings("CharsetObjectCanBeUsed")
private static final Charset UTF_8 = Charset.forName("UTF-8");
// @SuppressWarnings("CharsetObjectCanBeUsed")
// private static final Charset UTF_8 = Charset.forName("UTF-8");

private final @NotNull IHub hub;
private final @NotNull IEnvelopeReader envelopeReader;
@SuppressWarnings("UnusedVariable")
private final @NotNull ISerializer serializer;
private final @NotNull ILogger logger;

Expand Down Expand Up @@ -107,89 +108,97 @@ private void processEnvelope(final @NotNull SentryEnvelope envelope, final @Null
SentryLevel.DEBUG,
"Processing Envelope with %d item(s)",
CollectionUtils.size(envelope.getItems()));
int items = 0;

for (final SentryEnvelopeItem item : envelope.getItems()) {
items++;

if (item.getHeader() == null) {
logger.log(SentryLevel.ERROR, "Item %d has no header", items);
continue;
}
if (SentryItemType.Event.equals(item.getHeader().getType())) {
try (final Reader eventReader =
new BufferedReader(
new InputStreamReader(new ByteArrayInputStream(item.getData()), UTF_8))) {
SentryEvent event = serializer.deserialize(eventReader, SentryEvent.class);
if (event == null) {
logger.log(
SentryLevel.ERROR,
"Item %d of type %s returned null by the parser.",
items,
item.getHeader().getType());
} else {
if (envelope.getHeader().getEventId() != null
&& !envelope.getHeader().getEventId().equals(event.getEventId())) {
logger.log(
SentryLevel.ERROR,
"Item %d of has a different event id (%s) to the envelope header (%s)",
items,
envelope.getHeader().getEventId(),
event.getEventId());
continue;
}
hub.captureEvent(event, hint);
logger.log(SentryLevel.DEBUG, "Item %d is being captured.", items);

if (!waitFlush(hint)) {
logger.log(
SentryLevel.WARNING,
"Timed out waiting for event submission: %s",
event.getEventId());
break;
}
}
} catch (Exception e) {
logger.log(ERROR, "Item failed to process.", e);
}
} else {
// send unknown item types over the wire
final SentryEnvelope newEnvelope =
new SentryEnvelope(
envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item);
hub.captureEnvelope(newEnvelope, hint);
logger.log(
SentryLevel.DEBUG,
"%s item %d is being captured.",
item.getHeader().getType().getItemType(),
items);

if (!waitFlush(hint)) {
logger.log(
SentryLevel.WARNING,
"Timed out waiting for item type submission: %s",
item.getHeader().getType().getItemType());
break;
}
}

if (hint instanceof SubmissionResult) {
if (!((SubmissionResult) hint).isSuccess()) {
// Failed to send an item of the envelope: Stop attempting to send the rest (an attachment
// without the event that created it isn't useful)
logger.log(
SentryLevel.WARNING,
"Envelope had a failed capture at item %d. No more items will be sent.",
items);
break;
}
}

// reset the Hint to its initial state as we use it multiple times.
if (hint instanceof Resettable) {
((Resettable) hint).reset();
}
// int items = 0;

// for (final SentryEnvelopeItem item : envelope.getItems()) {
// items++;
//
// if (item.getHeader() == null) {
// logger.log(SentryLevel.ERROR, "Item %d has no header", items);
// continue;
// }
// if (SentryItemType.Event.equals(item.getHeader().getType())) {
// try (final Reader eventReader =
// new BufferedReader(
// new InputStreamReader(new ByteArrayInputStream(item.getData()), UTF_8))) {
// SentryEvent event = serializer.deserialize(eventReader, SentryEvent.class);
// if (event == null) {
// logger.log(
// SentryLevel.ERROR,
// "Item %d of type %s returned null by the parser.",
// items,
// item.getHeader().getType());
// } else {
// if (envelope.getHeader().getEventId() != null
// && !envelope.getHeader().getEventId().equals(event.getEventId())) {
// logger.log(
// SentryLevel.ERROR,
// "Item %d of has a different event id (%s) to the envelope header (%s)",
// items,
// envelope.getHeader().getEventId(),
// event.getEventId());
// continue;
// }
// hub.captureEvent(event, hint);
// logger.log(SentryLevel.DEBUG, "Item %d is being captured.", items);
//
// if (!waitFlush(hint)) {
// logger.log(
// SentryLevel.WARNING,
// "Timed out waiting for event submission: %s",
// event.getEventId());
// break;
// }
// }
// } catch (Exception e) {
// logger.log(ERROR, "Item failed to process.", e);
// }
// } else {
// // send unknown item types over the wire
// final SentryEnvelope newEnvelope =
// new SentryEnvelope(
// envelope.getHeader().getEventId(), envelope.getHeader().getSdkVersion(), item);
// hub.captureEnvelope(newEnvelope, hint);
// logger.log(
// SentryLevel.DEBUG,
// "%s item %d is being captured.",
// item.getHeader().getType().getItemType(),
// items);
//
// if (!waitFlush(hint)) {
// logger.log(
// SentryLevel.WARNING,
// "Timed out waiting for item type submission: %s",
// item.getHeader().getType().getItemType());
// break;
// }
// }
//
// if (hint instanceof SubmissionResult) {
// if (!((SubmissionResult) hint).isSuccess()) {
// // Failed to send an item of the envelope: Stop attempting to send the rest (an attachment
// // without the event that created it isn't useful)
// logger.log(
// SentryLevel.WARNING,
// "Envelope had a failed capture at item %d. No more items will be sent.",
// items);
// break;
// }
// }
//
// // reset the Hint to its initial state as we use it multiple times.
// if (hint instanceof Resettable) {
// ((Resettable) hint).reset();
// }
// }

// event and minidump need to be within the same envelope, so right now we are not enriching
// the event as a hacky solution, but event is gonna ne symbolicated using the minidump
hub.captureEnvelope(envelope, hint);
if (!waitFlush(hint)) {
return;
}
Comment on lines +195 to 200
Copy link
Contributor

Choose a reason for hiding this comment

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

we'd need to special case this if we go ahead with mini dumps, as we need to enrich the event but still sending all the left items within the same envelope


}

private boolean waitFlush(final @Nullable Object hint) {
Expand Down
11 changes: 9 additions & 2 deletions sentry/src/main/java/io/sentry/SentryEnvelopeItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ public final class SentryEnvelopeItem {

SentryEnvelopeItemHeader itemHeader =
new SentryEnvelopeItemHeader(
SentryItemType.Session, () -> cachedItem.getBytes().length, "application/json", null);
SentryItemType.Session,
() -> cachedItem.getBytes().length,
"application/json",
null,
null);

// Don't use method reference. This can cause issues on Android
return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes());
Expand Down Expand Up @@ -112,6 +116,7 @@ public final class SentryEnvelopeItem {
SentryItemType.resolve(event),
() -> cachedItem.getBytes().length,
"application/json",
null,
null);

// Don't use method reference. This can cause issues on Android
Expand Down Expand Up @@ -149,6 +154,7 @@ public static SentryEnvelopeItem fromUserFeedback(
SentryItemType.UserFeedback,
() -> cachedItem.getBytes().length,
"application/json",
null,
null);

// Don't use method reference. This can cause issues on Android
Expand Down Expand Up @@ -232,7 +238,8 @@ public static SentryEnvelopeItem fromAttachment(
SentryItemType.Attachment,
() -> cachedItem.getBytes().length,
attachment.getContentType(),
attachment.getFilename());
attachment.getFilename(),
attachment.getAttachmentType());

// Don't use method reference. This can cause issues on Android
return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes());
Expand Down
13 changes: 11 additions & 2 deletions sentry/src/main/java/io/sentry/SentryEnvelopeItemHeader.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public final class SentryEnvelopeItemHeader {
private final @NotNull SentryItemType type;
private final int length;
@Nullable private final Callable<Integer> getLength;
private final @Nullable String attachmentType;

public @NotNull SentryItemType getType() {
return type;
Expand Down Expand Up @@ -42,23 +43,31 @@ public int getLength() {
final @NotNull SentryItemType type,
int length,
final @Nullable String contentType,
final @Nullable String fileName) {
final @Nullable String fileName,
final @Nullable String attachmentType) {
this.type = Objects.requireNonNull(type, "type is required");
this.contentType = contentType;
this.length = length;
this.fileName = fileName;
this.getLength = null;
this.attachmentType = attachmentType;
}

SentryEnvelopeItemHeader(
final @NotNull SentryItemType type,
final @Nullable Callable<Integer> getLength,
final @Nullable String contentType,
final @Nullable String fileName) {
final @Nullable String fileName,
final @Nullable String attachmentType) {
this.type = Objects.requireNonNull(type, "type is required");
this.contentType = contentType;
this.length = -1;
this.fileName = fileName;
this.getLength = getLength;
this.attachmentType = attachmentType;
}

public @Nullable String getAttachmentType() {
return attachmentType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public void write(JsonWriter writer, SentryEnvelopeItemHeader value) throws IOEx
writer.value(value.getType().getItemType().toLowerCase(Locale.ROOT));
}

if (value.getAttachmentType() != null) {
writer.name("attachment_type");
writer.value(value.getAttachmentType());
}

writer.name("length");
writer.value(value.getLength());

Expand All @@ -51,6 +56,7 @@ public SentryEnvelopeItemHeader read(JsonReader reader) throws IOException {
String fileName = null;
SentryItemType type = SentryItemType.Unknown;
int length = 0;
String attachmentType = null;

reader.beginObject();
while (reader.hasNext()) {
Expand All @@ -71,13 +77,16 @@ public SentryEnvelopeItemHeader read(JsonReader reader) throws IOException {
case "length":
length = reader.nextInt();
break;
case "attachment_type":
attachmentType = reader.nextString();
break;
default:
reader.skipValue();
break;
}
}
reader.endObject();

return new SentryEnvelopeItemHeader(type, length, contentType, fileName);
return new SentryEnvelopeItemHeader(type, length, contentType, fileName, attachmentType);
}
}