Skip to content

Commit

Permalink
feat: stream envelope directly to file (#1021)
Browse files Browse the repository at this point in the history
  • Loading branch information
supervacuus authored Jul 30, 2024
1 parent d11589b commit 45fa26b
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 44 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

**Features**:

- Let the envelope serialization stream directly to the file. ([#1021](https://github.com/getsentry/sentry-native/pull/1021))

## 0.7.7

**Fixes**:
Expand Down
64 changes: 64 additions & 0 deletions src/path/sentry_path_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,67 @@ sentry__path_append_buffer(
return write_buffer_with_flags(
path, buf, buf_len, O_RDWR | O_CREAT | O_APPEND);
}

struct sentry_filewriter_s {
size_t byte_count;
int fd;
};

MUST_USE sentry_filewriter_t *
sentry__filewriter_new(const sentry_path_t *path)
{
int fd = open(path->path, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
if (fd < 0) {
return NULL;
}

sentry_filewriter_t *result = SENTRY_MAKE(sentry_filewriter_t);
if (!result) {
close(fd);
return NULL;
}

result->fd = fd;
result->byte_count = 0;
return result;
}

size_t
sentry__filewriter_write(
sentry_filewriter_t *filewriter, const char *buf, size_t buf_len)
{
if (!filewriter) {
return 0;
}
while (buf_len > 0) {
ssize_t n = write(filewriter->fd, buf, buf_len);
if (n < 0 && (errno == EAGAIN || errno == EINTR)) {
continue;
} else if (n <= 0) {
break;
}
filewriter->byte_count += n;
buf += n;
buf_len -= n;
}

return buf_len;
}

void
sentry__filewriter_free(sentry_filewriter_t *filewriter)
{
if (!filewriter) {
return;
}

close(filewriter->fd);
sentry_free(filewriter);
}

size_t
sentry__filewriter_byte_count(sentry_filewriter_t *filewriter)
{
return filewriter->byte_count;
}
63 changes: 63 additions & 0 deletions src/path/sentry_path_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,66 @@ sentry__path_append_buffer(
{
return write_buffer_with_mode(path, buf, buf_len, L"ab");
}

struct sentry_filewriter_s {
size_t byte_count;
FILE *f;
};

MUST_USE sentry_filewriter_t *
sentry__filewriter_new(const sentry_path_t *path)
{
FILE *f = _wfopen(path->path, L"wb");
if (!f) {
return NULL;
}

sentry_filewriter_t *result = SENTRY_MAKE(sentry_filewriter_t);
if (!result) {
fclose(f);
return NULL;
}

result->f = f;
result->byte_count = 0;
return result;
}

size_t
sentry__filewriter_write(
sentry_filewriter_t *filewriter, const char *buf, size_t buf_len)
{
if (!filewriter) {
return 0;
}
while (buf_len > 0) {
size_t n = fwrite(buf, 1, buf_len, filewriter->f);
if (n < 0 && (errno == EAGAIN || errno == EINTR)) {
continue;
} else if (n <= 0) {
break;
}
filewriter->byte_count += n;
buf += n;
buf_len -= n;
}

return buf_len;
}

void
sentry__filewriter_free(sentry_filewriter_t *filewriter)
{
if (!filewriter) {
return;
}
fflush(filewriter->f);
fclose(filewriter->f);
sentry_free(filewriter);
}

size_t
sentry__filewriter_byte_count(sentry_filewriter_t *filewriter)
{
return filewriter->byte_count;
}
2 changes: 1 addition & 1 deletion src/sentry_database.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool
sentry__run_write_session(
const sentry_run_t *run, const sentry_session_t *session)
{
sentry_jsonwriter_t *jw = sentry__jsonwriter_new(NULL);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
if (!jw) {
return false;
}
Expand Down
49 changes: 36 additions & 13 deletions src/sentry_envelope.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ sentry__envelope_add_event(sentry_envelope_t *envelope, sentry_value_t event)
return NULL;
}

sentry_jsonwriter_t *jw = sentry__jsonwriter_new(NULL);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
if (!jw) {
return NULL;
}
Expand Down Expand Up @@ -265,7 +265,7 @@ sentry__envelope_add_transaction(
return NULL;
}

sentry_jsonwriter_t *jw = sentry__jsonwriter_new(NULL);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
if (!jw) {
return NULL;
}
Expand Down Expand Up @@ -304,7 +304,7 @@ sentry__envelope_add_user_feedback(
return NULL;
}

sentry_jsonwriter_t *jw = sentry__jsonwriter_new(NULL);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
if (!jw) {
return NULL;
}
Expand Down Expand Up @@ -332,7 +332,7 @@ sentry__envelope_add_session(
if (!envelope || !session) {
return NULL;
}
sentry_jsonwriter_t *jw = sentry__jsonwriter_new(NULL);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
if (!jw) {
return NULL;
}
Expand Down Expand Up @@ -378,7 +378,7 @@ static void
sentry__envelope_serialize_headers_into_stringbuilder(
const sentry_envelope_t *envelope, sentry_stringbuilder_t *sb)
{
sentry_jsonwriter_t *jw = sentry__jsonwriter_new(sb);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(sb);
if (jw) {
sentry__jsonwriter_write_value(jw, envelope->contents.items.headers);
sentry__jsonwriter_free(jw);
Expand All @@ -389,7 +389,7 @@ static void
sentry__envelope_serialize_item_into_stringbuilder(
const sentry_envelope_item_t *item, sentry_stringbuilder_t *sb)
{
sentry_jsonwriter_t *jw = sentry__jsonwriter_new(sb);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(sb);
if (!jw) {
return;
}
Expand Down Expand Up @@ -476,16 +476,39 @@ MUST_USE int
sentry_envelope_write_to_path(
const sentry_envelope_t *envelope, const sentry_path_t *path)
{
// TODO: This currently builds the whole buffer in-memory.
// It would be nice to actually stream this to a file.
size_t buf_len = 0;
char *buf = sentry_envelope_serialize(envelope, &buf_len);
sentry_filewriter_t *fw = sentry__filewriter_new(path);

int rv = sentry__path_write_buffer(path, buf, buf_len);
if (envelope->is_raw) {
return envelope->contents.raw.payload_len
!= sentry__filewriter_write(fw, envelope->contents.raw.payload,
envelope->contents.raw.payload_len);
}

sentry_free(buf);
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_fw(fw);
if (jw) {
sentry__jsonwriter_write_value(jw, envelope->contents.items.headers);
sentry__jsonwriter_reset(jw);

return rv;
for (size_t i = 0; i < envelope->contents.items.item_count; i++) {
const sentry_envelope_item_t *item
= &envelope->contents.items.items[i];
const char newline = '\n';
sentry__filewriter_write(fw, &newline, sizeof(char));

sentry__jsonwriter_write_value(jw, item->headers);
sentry__jsonwriter_reset(jw);

sentry__filewriter_write(fw, &newline, sizeof(char));

sentry__filewriter_write(fw, item->payload, item->payload_len);
}
sentry__jsonwriter_free(jw);
}

size_t rv = sentry__filewriter_byte_count(fw);
sentry__filewriter_free(fw);

return rv == 0;
}

int
Expand Down
Loading

0 comments on commit 45fa26b

Please sign in to comment.