Skip to content

Conversation

@FranAguilera
Copy link
Contributor

@FranAguilera FranAguilera commented May 30, 2025

  • Forces internals of Logger.start() to always happen off the main thread
  • Add temporary in memory cache for any Logger.log(*) calls that happen during Logger.start() gets initialized

Verification

Session with a simulated expensive LoggerImpl creation and logs being emitted while start is in process

image image image

@FranAguilera FranAguilera changed the title [Android] Always force start internals into dedicated thread + add in… [Android] Force start to run off main thread May 30, 2025
@FranAguilera FranAguilera marked this pull request as draft May 30, 2025 13:34
@FranAguilera FranAguilera force-pushed the franjam/move-to-background branch 6 times, most recently from 639d69b to 788584f Compare June 2, 2025 09:56
@bitdriftlabs bitdriftlabs deleted a comment from github-actions bot Jun 2, 2025
@bitdriftlabs bitdriftlabs deleted a comment from github-actions bot Jun 2, 2025
@bitdriftlabs bitdriftlabs deleted a comment from github-actions bot Jun 2, 2025
@FranAguilera FranAguilera force-pushed the franjam/move-to-background branch from 3bb8b65 to b66365b Compare June 12, 2025 13:24
@bitdriftlabs bitdriftlabs deleted a comment from github-actions bot Jun 12, 2025
@FranAguilera FranAguilera force-pushed the franjam/move-to-background branch from 9bcdf6b to 80dc8ad Compare June 16, 2025 09:42
@bitdriftlabs bitdriftlabs deleted a comment from github-actions bot Jun 16, 2025
@github-actions
Copy link

📦 APK Size Report

Metric Size (KB)
Baseline 3602
Current 3606
Difference 4

❌ APK size increased by 4 KB.

@FranAguilera FranAguilera force-pushed the franjam/move-to-background branch from 80dc8ad to ff8df1e Compare June 18, 2025 10:53
@github-actions
Copy link

📦 APK Size Report

Metric Size (KB)
Baseline 3602
Current 3606
Difference 4

❌ APK size increased by 4 KB.

@FranAguilera FranAguilera marked this pull request as ready for review June 18, 2025 11:41

private companion object {
private const val DEFAULT_NOT_SETUP_MESSAGE = "SDK starting"
private const val MAX_LOG_CALL_SIZE = 1024
Copy link
Contributor

Choose a reason for hiding this comment

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

what does this size represent? is it the number of function types stored in the heap?

and how was this size determined? does it match the number in the pre-config buffer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's right, is the max number of logger function calls stored (though will remove oldest entries if value is reached to append new ones at the end). The size was a bit arbitrary but big enough to capture most recent calls. I can do a follow up to investigate an ideal size but i think is good threshold to start testing on the field

Copy link
Contributor

Choose a reason for hiding this comment

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

for reference, if you want to use the preconfigbuffer as inspiration: it's bounded not only by count but also by memory size (in bytes), and the current limits are 512, and 1 MB

Copy link
Contributor Author

Choose a reason for hiding this comment

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

awesome thanks, will match current size for now

Comment on lines 88 to 90
val span = Span(null, name, level, fields, startTimeMs, parentSpanId)
addLoggerCall { it.startSpan(name, level, fields, startTimeMs, parentSpanId) }
return span
Copy link
Contributor

Choose a reason for hiding this comment

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

did you verify that this correctly closes the span? seems like we might be returning a span with a null logger so it won't ever be closed with a logger?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yeah good catch, adding a follow up task to track this and verify. I think this will be such a short time live that may not break critical spans (🤞 )

Copy link
Contributor Author

@FranAguilera FranAguilera Jun 18, 2025

Choose a reason for hiding this comment

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

nvm, will try to pass the loggerImpl call here somehow when flushing to native

Copy link
Contributor Author

@FranAguilera FranAguilera Jun 19, 2025

Choose a reason for hiding this comment

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

Did a minor update and verified the spans works as expected. Here in this session we start a span on initial fragment load and we stopped upon copy session url click. There is also an artificial delay for LoggerImpl creation of 2 seconds

image image image image

Comment on lines +64 to +71
override fun log(
level: LogLevel,
fields: Map<String, String>?,
throwable: Throwable?,
message: () -> String,
) {
addLoggerCall { it.log(level, fields, throwable, message) }
}
Copy link
Contributor

Choose a reason for hiding this comment

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

One potential issue with this is that the timestamp of the logs will be at the time that they were replayed, not the actual time they were logged? Maybe fine for now but something to keep in mind

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes i agree, it's not perfect as they will be called sequentially but not at the original timestamp. I will create follow up task

Copy link
Contributor

Choose a reason for hiding this comment

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

something that we could do is to evaluate the DateProvider eagerly when we receive a log and store the timestamp along with the log function call in the ConcurrentLinkedQueue, but of course this would need our rust logger to have a way to override timestamps

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup i thought something like that before but will need to tweak the rust layer

fatalIssueReporter = fatalIssueReporter,
preInitLogFlusher = preInitInMemoryLogger,
)
default.set(LoggerState.Started(loggerImpl))
Copy link
Contributor

Choose a reason for hiding this comment

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

From a concurrency perspective it seems like there might be a chance that logs are written to the in memory queue after it gets cleared but before we update the LoggerState, which seems like it could result in dropped logs?

I don't have a good solution for how to avoid this without making it significantly more complicated so maybe it's fine?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, probably ok i think the init time should be in order of ms (hundred of ms at most). One think to keep in mind is that the backing CommonBackground Thread io.bitdrift.capture.background-thread-worker is a single threaded one and everything within the backgroundThreadHandler.runAsync should be sequential

@FranAguilera FranAguilera enabled auto-merge (squash) June 19, 2025 10:21
@github-actions
Copy link

📦 APK Size Report

Metric Size (KB)
Baseline 3606
Current 3606
Difference 0

✅ APK size unchanged.

@FranAguilera FranAguilera merged commit c375bdf into main Jun 19, 2025
14 checks passed
@FranAguilera FranAguilera deleted the franjam/move-to-background branch June 19, 2025 10:34
@github-actions github-actions bot locked and limited conversation to collaborators Jun 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants