Skip to content

Commit 4ede812

Browse files
feat(logs): add sentry log API + send first logs (#1272)
* add sentry log API + send first logs * fix log_level_as_string * attach attributes to logs * attach formatted message + args * add to example * add more attributes * cleanup * windows warning-as-error * windows warning-as-error v2 * windows warning-as-error v2 (final) * add unit tests for initial logs * memleak attempted fix * memleak attempted fix 2 * cleanup * use `sentry_level_t` instead of new log level enum * add SENTRY_LEVEL_TRACE to sentry_logger * quick anti-brownout fix - see #1274 * fix missing SENTRY_LEVEL_INFO string return * fix logger level check + add test * cleanup logs parameter extraction * warn-as-error fix * const char* fix * static function * feat(logs): add (u)int64 sentry_value_t type (#1301) * add (u)int64 sentry_value_t type * add value_to_msgpack missing switch cases * remove undefined behavior test (C99 6.3.1.4) * avoid Windows sized integer name collision * cleanup & apply code review feedback * more cleanup & remove type coercion * update logs param conversion * own uint64 string * apply suggestions from code review
1 parent c83b3ee commit 4ede812

20 files changed

+993
-22
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ jobs:
121121
SYSTEM_VERSION_COMPAT: 0
122122
RUN_ANALYZER: asan,llvm-cov
123123
- name: Windows (old VS, 32-bit)
124-
os: windows-2019
124+
os: windows-2022
125125
TEST_X86: 1
126126
- name: Windows (latest)
127127
os: windows-latest

examples/example.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,26 @@ main(int argc, char **argv)
359359

360360
sentry_init(options);
361361

362+
// TODO incorporate into test
363+
if (sentry_options_get_enable_logs(options)) {
364+
sentry_log_trace("We log it up %i%%, %s style", 100, "trace");
365+
sentry_log_debug("We log it up %i%%, %s style", 100, "debug");
366+
sentry_log_info("We log it up %i%%, %s style", 100, "info");
367+
sentry_log_warn("We log it up %i%%, %s style", 100, "warn");
368+
sentry_log_error("We log it up %i%%, %s style", 100, "error");
369+
sentry_log_fatal("We log it up %i%%, %s style", 100, "fatal");
370+
371+
// Test the logger with various parameter types
372+
sentry_log_info(
373+
"API call to %s completed in %d ms with %f success rate",
374+
"/api/products", 2500, 0.95);
375+
376+
sentry_log_warn("Processing %d items, found %u errors, pointer: %p",
377+
100, 5u, (void *)0x12345678);
378+
379+
sentry_log_error("Character '%c' is invalid", 'X');
380+
}
381+
362382
if (!has_arg(argc, argv, "no-setup")) {
363383
sentry_set_transaction("test-transaction");
364384
sentry_set_level(SENTRY_LEVEL_WARNING);
@@ -566,6 +586,9 @@ main(int argc, char **argv)
566586
SENTRY_LEVEL_INFO, "my-logger", "Hello World!");
567587
sentry_capture_event(event);
568588
}
589+
if (sentry_options_get_enable_logs(options)) {
590+
sentry_log_debug("logging after scoped transaction event");
591+
}
569592

570593
sentry_transaction_finish(tx);
571594
}

include/sentry.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ typedef enum {
137137
SENTRY_VALUE_TYPE_NULL,
138138
SENTRY_VALUE_TYPE_BOOL,
139139
SENTRY_VALUE_TYPE_INT32,
140+
SENTRY_VALUE_TYPE_INT64,
141+
SENTRY_VALUE_TYPE_UINT64,
140142
SENTRY_VALUE_TYPE_DOUBLE,
141143
SENTRY_VALUE_TYPE_STRING,
142144
SENTRY_VALUE_TYPE_LIST,
@@ -200,6 +202,16 @@ SENTRY_API sentry_value_t sentry_value_new_null(void);
200202
*/
201203
SENTRY_API sentry_value_t sentry_value_new_int32(int32_t value);
202204

205+
/**
206+
* Creates a new 64-bit signed integer value.
207+
*/
208+
SENTRY_API sentry_value_t sentry_value_new_int64(int64_t value);
209+
210+
/**
211+
* Creates a new 64-bit unsigned integer value.
212+
*/
213+
SENTRY_API sentry_value_t sentry_value_new_uint64(uint64_t value);
214+
203215
/**
204216
* Creates a new double value.
205217
*/
@@ -338,6 +350,16 @@ SENTRY_API size_t sentry_value_get_length(sentry_value_t value);
338350
*/
339351
SENTRY_API int32_t sentry_value_as_int32(sentry_value_t value);
340352

353+
/**
354+
* Converts a value into a 64 bit signed integer.
355+
*/
356+
SENTRY_API int64_t sentry_value_as_int64(sentry_value_t value);
357+
358+
/**
359+
* Converts a value into a 64 bit unsigned integer.
360+
*/
361+
SENTRY_API uint64_t sentry_value_as_uint64(sentry_value_t value);
362+
341363
/**
342364
* Converts a value into a double value.
343365
*/
@@ -370,6 +392,7 @@ SENTRY_API char *sentry_value_to_json(sentry_value_t value);
370392
* Sentry levels for events and breadcrumbs.
371393
*/
372394
typedef enum sentry_level_e {
395+
SENTRY_LEVEL_TRACE = -2,
373396
SENTRY_LEVEL_DEBUG = -1,
374397
SENTRY_LEVEL_INFO = 0,
375398
SENTRY_LEVEL_WARNING = 1,
@@ -1750,6 +1773,13 @@ SENTRY_EXPERIMENTAL_API void sentry_options_set_enable_logs(
17501773
SENTRY_EXPERIMENTAL_API int sentry_options_get_enable_logs(
17511774
const sentry_options_t *opts);
17521775

1776+
SENTRY_EXPERIMENTAL_API void sentry_log_trace(const char *message, ...);
1777+
SENTRY_EXPERIMENTAL_API void sentry_log_debug(const char *message, ...);
1778+
SENTRY_EXPERIMENTAL_API void sentry_log_info(const char *message, ...);
1779+
SENTRY_EXPERIMENTAL_API void sentry_log_warn(const char *message, ...);
1780+
SENTRY_EXPERIMENTAL_API void sentry_log_error(const char *message, ...);
1781+
SENTRY_EXPERIMENTAL_API void sentry_log_fatal(const char *message, ...);
1782+
17531783
#ifdef SENTRY_PLATFORM_LINUX
17541784

17551785
/**

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ sentry_target_sources_cwd(sentry
1515
sentry_json.h
1616
sentry_logger.c
1717
sentry_logger.h
18+
sentry_logs.c
19+
sentry_logs.h
1820
sentry_options.c
1921
sentry_options.h
2022
sentry_os.c

src/sentry_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ sentry_init(sentry_options_t *options)
125125
sentry_close();
126126

127127
sentry_logger_t logger = { NULL, NULL, SENTRY_LEVEL_DEBUG };
128+
128129
if (options->debug) {
129130
logger = options->logger;
130131
}

src/sentry_envelope.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,32 @@ sentry__envelope_add_transaction(
295295
return item;
296296
}
297297

298+
sentry_envelope_item_t *
299+
sentry__envelope_add_logs(sentry_envelope_t *envelope, sentry_value_t logs)
300+
{
301+
sentry_envelope_item_t *item = envelope_add_item(envelope);
302+
if (!item) {
303+
return NULL;
304+
}
305+
306+
sentry_jsonwriter_t *jw = sentry__jsonwriter_new_sb(NULL);
307+
if (!jw) {
308+
return NULL;
309+
}
310+
311+
sentry__jsonwriter_write_value(jw, logs);
312+
item->payload = sentry__jsonwriter_into_string(jw, &item->payload_len);
313+
314+
sentry__envelope_item_set_header(
315+
item, "type", sentry_value_new_string("log"));
316+
sentry__envelope_item_set_header(item, "item_count",
317+
sentry_value_new_int32((int32_t)sentry_value_get_length(logs)));
318+
sentry__envelope_item_set_header(item, "content_type",
319+
sentry_value_new_string("application/vnd.sentry.items.log+json"));
320+
321+
return item;
322+
}
323+
298324
sentry_envelope_item_t *
299325
sentry__envelope_add_user_feedback(
300326
sentry_envelope_t *envelope, sentry_value_t user_feedback)

src/sentry_envelope.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ sentry_envelope_item_t *sentry__envelope_add_event(
4242
sentry_envelope_item_t *sentry__envelope_add_transaction(
4343
sentry_envelope_t *envelope, sentry_value_t transaction);
4444

45+
/**
46+
* Add a list of logs to this envelope.
47+
*/
48+
sentry_envelope_item_t *sentry__envelope_add_logs(
49+
sentry_envelope_t *envelope, sentry_value_t logs);
50+
4551
/**
4652
* Add a user feedback to this envelope.
4753
*/

src/sentry_json.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,26 @@ sentry__jsonwriter_write_int32(sentry_jsonwriter_t *jw, int32_t val)
364364
}
365365
}
366366

367+
void
368+
sentry__jsonwriter_write_int64(sentry_jsonwriter_t *jw, int64_t val)
369+
{
370+
if (can_write_item(jw)) {
371+
char buf[24];
372+
snprintf(buf, sizeof(buf), "%" PRId64, val);
373+
write_str(jw, buf);
374+
}
375+
}
376+
377+
void
378+
sentry__jsonwriter_write_uint64(sentry_jsonwriter_t *jw, uint64_t val)
379+
{
380+
if (can_write_item(jw)) {
381+
char buf[24];
382+
snprintf(buf, sizeof(buf), "%" PRIu64, val);
383+
write_str(jw, buf);
384+
}
385+
}
386+
367387
void
368388
sentry__jsonwriter_write_double(sentry_jsonwriter_t *jw, double val)
369389
{

src/sentry_json.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ void sentry__jsonwriter_write_bool(sentry_jsonwriter_t *jw, bool val);
5353
*/
5454
void sentry__jsonwriter_write_int32(sentry_jsonwriter_t *jw, int32_t val);
5555

56+
/**
57+
* Write a 64-bit signed integer, encoded as JSON number.
58+
*/
59+
void sentry__jsonwriter_write_int64(sentry_jsonwriter_t *jw, int64_t val);
60+
61+
/**
62+
* Write a 64-bit unsigned integer, encoded as JSON number.
63+
*/
64+
void sentry__jsonwriter_write_uint64(sentry_jsonwriter_t *jw, uint64_t val);
65+
5666
/**
5767
* Write a 64-bit float, encoded as JSON number.
5868
*/

src/sentry_logger.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ const char *
6969
sentry__logger_describe(sentry_level_t level)
7070
{
7171
switch (level) {
72+
case SENTRY_LEVEL_TRACE:
73+
return "TRACE ";
7274
case SENTRY_LEVEL_DEBUG:
7375
return "DEBUG ";
7476
case SENTRY_LEVEL_INFO:
@@ -87,8 +89,7 @@ sentry__logger_describe(sentry_level_t level)
8789
void
8890
sentry__logger_log(sentry_level_t level, const char *message, ...)
8991
{
90-
if (g_logger.logger_level != SENTRY_LEVEL_DEBUG
91-
&& level < g_logger.logger_level) {
92+
if (level < g_logger.logger_level) {
9293
return;
9394
}
9495
sentry_logger_t logger = g_logger;

0 commit comments

Comments
 (0)