Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: stream envelope directly to file #1021

Merged
merged 10 commits into from
Jul 30, 2024
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);
supervacuus marked this conversation as resolved.
Show resolved Hide resolved
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);
supervacuus marked this conversation as resolved.
Show resolved Hide resolved
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
Loading