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: add more db info on span data #3231

Merged
merged 8 commits into from
Aug 29, 2023

Conversation

armcknight
Copy link
Member

@armcknight armcknight commented Aug 17, 2023

📜 Description

Add the persistent store types and URLs to the span data for Core Data tracking.

Also a couple refactors:

  • fix a copypasta variable name and log statement that were "fetch" but should've been "save"
  • the fetch tracker method grabs a span inside block scope and then the rest of the method proceeds afterwards; but in save tracking, it's all done in the block scope. bump out the save method's logic to match the fetch method's (less indentation -> more code per line).
  • rename method to be more descriptive
  • moved/combined SentryCoreDataTrackerTests.TestNSManagedContext to TestCoreDataStack.managedObjectContext

💡 Motivation and Context

#3212

@github-actions
Copy link

github-actions bot commented Aug 17, 2023

Fails
🚫 Please consider adding a changelog entry for the next release.
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

- add more db info on span data ([#3231](https://github.com/getsentry/sentry-cocoa/pull/3231))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description.

Generated by 🚫 dangerJS against bc5e393

Comment on lines +117 to +129
NSMutableArray<NSString *> *systems = [NSMutableArray<NSString *> array];
NSMutableArray<NSString *> *names = [NSMutableArray<NSString *> array];
[context.persistentStoreCoordinator.persistentStores enumerateObjectsUsingBlock:^(
__kindof NSPersistentStore *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
[systems addObject:obj.type];
if (obj.URL != nil) {
[names addObject:obj.URL.path];
} else {
[names addObject:@"(null)"];
}
}];
[span setDataValue:[systems componentsJoinedByString:@";"] forKey:@"db.system"];
[span setDataValue:[names componentsJoinedByString:@";"] forKey:@"db.name"];
Copy link
Member Author

Choose a reason for hiding this comment

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

The new db.name and db.system data.

Comment on lines -81 to +76
__block id<SentrySpan> fetchSpan = nil;
__block id<SentrySpan> saveSpan = nil;
Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed this variable

Comment on lines -91 to +96
if (fetchSpan) {
[SentryLog
logWithMessage:[NSString
stringWithFormat:@"SentryCoreDataTracker automatically "
@"started a new span with description: %@, "
@"operation: %@",
fetchSpan.description, SENTRY_COREDATA_FETCH_OPERATION]
andLevel:kSentryLevelDebug];

[fetchSpan setDataValue:operations forKey:@"operations"];
}
saveSpan = [span startChildWithOperation:SENTRY_COREDATA_SAVE_OPERATION
description:[self descriptionForOperations:operations
inContext:context]];
saveSpan.origin = SentryTraceOriginAutoDBCoreData;
}];

if (saveSpan) {
SENTRY_LOG_DEBUG(@"SentryCoreDataTracker automatically started a new span with "
@"description: %@, operation: %@",
saveSpan.description, saveSpan.operation);

[saveSpan setDataValue:operations forKey:@"operations"];
} else {
SENTRY_LOG_ERROR(@"managedObjectContext:save:originalImp: saveSpan is nil");
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved this out of the useSpan: scope, like the code for fetch operations.

stringWithFormat:@"SentryCoreDataTracker automatically "
@"started a new span with description: %@, "
@"operation: %@",
fetchSpan.description, SENTRY_COREDATA_FETCH_OPERATION]
Copy link
Member Author

Choose a reason for hiding this comment

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

This should've been SENTRY_COREDATA_SAVE_OPERATION, but I did one better and just access SentrySpan.operation for both such logs (here and in fetches)

Comment on lines -118 to +112
- (void)mainThreadExtraInfo:(SentrySpan *)span
- (void)addExtraInfoToSpan:(SentrySpan *)span withContext:(NSManagedObjectContext *)context
Copy link
Member Author

Choose a reason for hiding this comment

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

Renamed this method as it's doing more than just main thread stuff now.

Comment on lines -47 to +49
[SentryLog
logWithMessage:[NSString stringWithFormat:
@"SentryCoreDataTracker automatically "
@"started a new span with description: %@, operation: %@",
fetchSpan.description, SENTRY_COREDATA_FETCH_OPERATION]
andLevel:kSentryLevelDebug];
SENTRY_LOG_DEBUG(@"SentryCoreDataTracker automatically started a new span with "
@"description: %@, operation: %@",
fetchSpan.description, fetchSpan.operation);
Copy link
Member Author

Choose a reason for hiding this comment

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

Converted all the logs to the new macros. Also here's the second place I changed interpolating the operation constant for SentrySpan.operation.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for doing this 👍

@github-actions
Copy link

github-actions bot commented Aug 17, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1245.02 ms 1248.88 ms 3.86 ms
Size 22.84 KiB 404.25 KiB 381.41 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
c2ec420 1256.27 ms 1269.24 ms 12.97 ms
e24290f 1239.94 ms 1248.28 ms 8.34 ms
28333b6 1186.29 ms 1225.18 ms 38.89 ms
a176fc4 1239.78 ms 1258.98 ms 19.20 ms
794f87f 1225.78 ms 1243.46 ms 17.68 ms
3cba0e8 1250.86 ms 1258.39 ms 7.53 ms
7cd187e 1196.51 ms 1226.04 ms 29.53 ms
9e96fd6 1207.20 ms 1229.40 ms 22.20 ms
0776564 1224.35 ms 1247.26 ms 22.91 ms
25e65a5 1249.08 ms 1277.78 ms 28.70 ms

App size

Revision Plain With Sentry Diff
c2ec420 20.76 KiB 401.65 KiB 380.89 KiB
e24290f 22.84 KiB 403.51 KiB 380.66 KiB
28333b6 20.76 KiB 424.69 KiB 403.93 KiB
a176fc4 22.84 KiB 403.24 KiB 380.39 KiB
794f87f 20.76 KiB 401.37 KiB 380.61 KiB
3cba0e8 22.84 KiB 403.19 KiB 380.34 KiB
7cd187e 20.76 KiB 401.66 KiB 380.90 KiB
9e96fd6 20.76 KiB 425.80 KiB 405.04 KiB
0776564 20.76 KiB 399.19 KiB 378.43 KiB
25e65a5 22.85 KiB 403.19 KiB 380.34 KiB

Previous results on branch: armcknight/feat/3212-db-attributes-on-span-data

Startup times

Revision Plain With Sentry Diff
5c85b82 1213.31 ms 1228.29 ms 14.98 ms

App size

Revision Plain With Sentry Diff
5c85b82 22.84 KiB 404.25 KiB 381.41 KiB

@codecov
Copy link

codecov bot commented Aug 17, 2023

Codecov Report

Merging #3231 (8251982) into main (91d2d63) will increase coverage by 0.055%.
The diff coverage is 89.830%.

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##              main     #3231       +/-   ##
=============================================
+ Coverage   89.153%   89.209%   +0.055%     
=============================================
  Files          502       502               
  Lines        54213     54225       +12     
  Branches     19457     19469       +12     
=============================================
+ Hits         48333     48374       +41     
+ Misses        5014      4990       -24     
+ Partials       866       861        -5     
Files Changed Coverage Δ
...tions/Performance/CoreData/TestCoreDataStack.swift 82.653% <77.777%> (-2.874%) ⬇️
Sources/Sentry/SentryCoreDataTracker.m 94.482% <82.857%> (-1.201%) ⬇️
...rformance/CoreData/SentryCoreDataTrackerTest.swift 94.771% <100.000%> (+3.453%) ⬆️

... and 11 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 91d2d63...8251982. Read the comment docs.

Comment on lines +336 to +339
XCTAssertEqual(try XCTUnwrap(dbSpan.data["db.system"] as? String), "SQLite")
XCTAssert(try XCTUnwrap(dbSpan.data["db.name"] as? NSString).contains(TestCoreDataStack.databaseFilename))
Copy link
Member Author

Choose a reason for hiding this comment

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

Assertions for the new properties

Copy link
Member

Choose a reason for hiding this comment

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

l: maybe re-add the assert for origin and read_count (for read operations)

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch, i removed those by accident

override var hasChanges: Bool {
return ((inserted?.count ?? 0) > 0) ||
((deleted?.count ?? 0) > 0) ||
((updated?.count ?? 0) > 0) || super.hasChanges
Copy link
Member Author

Choose a reason for hiding this comment

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

Had to add || super.hasChanges for SentryCoreDataTrackerTests.test_Save() to work again, because it doesn't rely on the subclass properties.

if (obj.URL != nil) {
[names addObject:obj.URL.path];
} else {
[names addObject:@"(null)"];
Copy link
Contributor

Choose a reason for hiding this comment

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

h: I believe we need a better option to fallback. This is not user friendly and I'm foreseeing complains.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm open to any alternatives. Nobody has proposed any so far.

Copy link
Member Author

@armcknight armcknight Aug 18, 2023

Choose a reason for hiding this comment

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

I would also be interested to know the cases where the URL is nil. I expected it to be nil for in memory stores, but even that has a value like memory://563428497. It is probably nil if there is no persistent store/coordinator at all, but then I don't know what the complaint would be. In that case I question if we should even be reporting anything at all, but that kind of refactor is out of scope for this issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm open to any alternatives.

<App Name>:coredata anything really other than (null)

Copy link
Member Author

@armcknight armcknight Aug 21, 2023

Choose a reason for hiding this comment

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

We already gather the equivalent of that in the type.

In this case, we should send some kind of sentinel value so the frontend knows to render a special state equivalent to "there was no database". This seems as good as any.

If I were a customer I would rather know that this value was not available, vs having it covered up by a default value like what you're proposing. It could help find an upstream error.

Copy link
Member

@kahest kahest Aug 29, 2023

Choose a reason for hiding this comment

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

I agree with @armcknight here - in case this occurs a lot and provides not enough context we can always re-iterate.

Copy link
Member

@kahest kahest left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for the opportunistic refactoring as well 💯

Comment on lines -47 to +49
[SentryLog
logWithMessage:[NSString stringWithFormat:
@"SentryCoreDataTracker automatically "
@"started a new span with description: %@, operation: %@",
fetchSpan.description, SENTRY_COREDATA_FETCH_OPERATION]
andLevel:kSentryLevelDebug];
SENTRY_LOG_DEBUG(@"SentryCoreDataTracker automatically started a new span with "
@"description: %@, operation: %@",
fetchSpan.description, fetchSpan.operation);
Copy link
Member

Choose a reason for hiding this comment

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

Thank you for doing this 👍

Comment on lines +336 to +339
XCTAssertEqual(try XCTUnwrap(dbSpan.data["db.system"] as? String), "SQLite")
XCTAssert(try XCTUnwrap(dbSpan.data["db.name"] as? NSString).contains(TestCoreDataStack.databaseFilename))
Copy link
Member

Choose a reason for hiding this comment

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

l: maybe re-add the assert for origin and read_count (for read operations)

@armcknight armcknight force-pushed the armcknight/feat/3212-db-attributes-on-span-data branch from e902924 to 9fd258d Compare August 29, 2023 18:36
@armcknight armcknight merged commit 87e0836 into main Aug 29, 2023
40 of 43 checks passed
@armcknight armcknight deleted the armcknight/feat/3212-db-attributes-on-span-data branch August 29, 2023 19:33
@kahest kahest linked an issue Aug 30, 2023 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Starfish] Add db attributes to database span's span data
3 participants