square / aardvark Goto Github PK
View Code? Open in Web Editor NEWAardvark is a library that makes it dead simple to create actionable bug reports.
License: Apache License 2.0
Aardvark is a library that makes it dead simple to create actionable bug reports.
License: Apache License 2.0
-[ARKLogDistributorTests test_distributeAllPendingLogsWithCompletionHandler_informsLogObserversOfAllPendingLogs]
failed once in CI. Specifically XCTAssertEqual([ARKLogDistributor defaultDistributor].internalQueueOperationCount, 0);
failed because [ARKLogDistributor defaultDistributor].internalQueueOperationCount == 1
when that line ran. Likely due to parallelization of tests. Need to investigate
This stems from a desire to have bug reporters (in particular the ARKEmailBugReporter
) treat the log store as just another attachment, rather than special casing it. Currently the only major behavioral difference between the log stores and the other attachments is that the reporter pulls the recent errors out of the logs and surfaces them at the top level. This is vital behavior in the case where attachments aren't available, but it's also very useful when there are attachments to provide a quick hint as to what the problem might be before digging into each attachment.
I think it would be fairly straightforward to introduce a highlightsSummary
property (exact naming TBD) to ARKBugReportAttachment
so that any attachment could optionally surface highlights at the top level. This would also unblock making the log store be a regular attachment, since the recent error logic could be easily moved to the LogStoreAttachmentGenerator
.
ARKDataArchive.m:41:17: Method override for the designated initializer of the superclass '-init' not found.
I fixed it locally by removing NS_DESIGNATED_INITIALIZER on ARKDataArchive.h:28
The AardvarkLoggingUI podspec has a source file pattern that matches Swift code however the pod is Objective-C only.
s.source_files = 'Sources/AardvarkLoggingUI/**/*.{h,m,swift}'
Currently, screenshots are included in bug reports by adding them to a log message. This means that if you don't include a log store in a bug report (either by having the emailAttachmentAdditionsDelegate
filter it out or the promptingDelegate
removing it from the configuration), the screenshot taken when filing the bug report will not be attached to the email.
Currently, the view hierarchy description can only be included when a screenshot is also included.
/// If this bug report includes a screenshot, also attach a description of the view hierarchy. Defaults to YES.
@property (nonatomic) BOOL attachesViewHierarchyDescriptionWithScreenshot;
This dependency is unnecessary and should be removed.
Per conversation with @dfed -- it'd be really handy if Aardvark was able to (via opt-in, of course) log Foundation's network requests as they went by. This is fairly straightforward to do using URLProtocol.
There are several calls to NSFileHandle's writeData inNSFileHandle+ARKAdditions.m
which is deprecated.
API_DEPRECATED_WITH_REPLACEMENT("writeData:error:",
macos(10.0, API_TO_BE_DEPRECATED), ios(2.0, API_TO_BE_DEPRECATED),
watchos(2.0, API_TO_BE_DEPRECATED), tvos(9.0, API_TO_BE_DEPRECATED));
The problem here is that this old method will raise an exception in case of an error, especially if the device runs out of disk space:
If the receiver is a file, writing takes place at the file pointerβs current position. After it writes the data, the method advances the file pointer by the number of bytes written. **This method raises an exception if the file descriptor is closed or is not valid, if the receiver represents an unconnected pipe or socket endpoint, if no free space is left on the file system, or if any other writing error occurs.
Using the newer writeData:error:
selector would return an error instead of causing an exception.
Follow-up to #53 to also flush all observers, not just the distributor
xcode 10.1
Aardvark.swift is missing @objc
before method.
The default log store get lazily created the first time you access the defaultLogStore
property. If you follow the one-line setup approach, this happens immediately since we access the default log store in order to create the bug reporter. If you don't use this setup, however, instead opting to create the bug reporter later, calling log(...)
will send the message nowhere (or really will send the message to other log observers you've added, but not the default log store).
I think the expected behavior would be to create the default log store the first time log(...)
is called if it doesn't already exist.
I want my iOS guys to start using this but all our dependencies are SPM. It would be rad if this was also available via Swift Package Manager. π
Aardvark currently has a lot of responsibilities - adding log messages, viewing those log messages in the app, generating data for a bug report, and sending that bug report via email. Breaking it down into smaller modules unlocks a couple of distinct advantages:
The disadvantage comes in the form of a few extra sets in setting up the dependencies (since there are now more dependencies) and discoverability of new features (since they may be in a not-yet-imported module), but I think these are greatly outweighed by the advantages.
The current frameworks (Aardvark and CoreAardvark) will be broken down into four separate frameworks based on functionality. Frameworks related to the logging functionality with be prefixed with "CoreAardvark" (where CoreAardvark
itself is the core logging framework) and frameworks related to the bug reporting functionality will be prefixed with "Aardvark" (where Aardvark
itself is the core bug reporting framework). This gives us:
This provides us with a solid foundation to build out new logging and bug reporting functionality in a modular fashion on top of the two core frameworks, CoreAardvark and Aardvark.
In the interest of making the addition of new bug reporting flows simpler, I think we should keep the bug report "attachment" concept in the main Aardvark framework. Since it isn't inherently tied to the mail concepts right now, the only change to the class will be a rename from ARKEmailAttachment
to ARKBugReportAttachment
.
We can then begin to add new modules over time, which will generally fall into one of the following categories for most cases:
With this, the frameworks will be broken down into small components and restructured as follows:
Current | Proposed | |
---|---|---|
Log methods (Aardvark.log() , ARKLog() , ARKLogWithType() ) |
CoreAardvark | CoreAardvark |
Log message primitives (ARKLogMessage , ARKLogType ) |
CoreAardvark | CoreAardvark |
Log storage (ARKLogStore , ARKDataArchive , file management utilities) |
CoreAardvark | CoreAardvark |
Log distribution (ARKLogDistributor , ARKLogObserver ) |
CoreAardvark | CoreAardvark |
Exception logging (ARKExceptionLogging ) |
CoreAardvark | CoreAardvark |
Log formatting (ARKLogFormatter , ARKDefaultLogFormatter |
Aardvark | CoreAardvark |
In-app log viewing (view controllers and sharing utilities) | Aardvark | CoreAardvarkLoggingUI |
Screenshot logging (ARKLogScreenshot() and distributor additions) |
Aardvark | Aardvark |
Bug reporter protocol (ARKBugReporter ) |
Aardvark | Aardvark |
Bug report attachments (ARKBugReportAttachment ) |
Aardvark | Aardvark |
Convenience method to add (generic) bug reporter via gesture | Aardvark | Aardvark |
Email bug reporter (ARKEmailBugReporter , ARKEmailBugReportConfiguration ) |
Aardvark | AardvarkMailUI |
Convenience method to add email bug reporter via gesture | Aardvark | AardvarkMailUI |
Currently if you follow the README and use Aardvark.addDefaultBugReportingGestureWithEmailBugReporter()
to setup Aardvark you will get an unlimited amount of logs stored to disk. After a while that adds up to a lot of disk and will cause issues. I think it'd be reasonable for defaultLogStore
to have maximumLogMessageCount set to a reasonable value (5,000?) to prevent this.
ARKLogDistributorTests.test_logDistribution_performance()
was disabled in #80 since it was observed to be flaky on CI builds. Specifically, the tearDown
method was timing out while trying to clear the log store after running the test. I could never reproduce this failure locally, and attempts to increase the timeout did not resolve this issue.
We should investigate why this was flaking and reenable the test once we have a fix.
Currently this explicitly sets the text color to black, which doesn't work correctly in dark mode.
In apps that use a UISceneDelegate
, the ARKEmailBugReporter
does not present the mail composer after completing the initial prompt.
Just a simple search that filters the logs based on a query
Currently if a customer does not have a Mail.app account configured, Aardvark's email reporter does not include attachments like logs and screenshots (which are so useful). For the common case of Gmail accounts, Aardvark could utilize Google's iOS library to send attachments directly from Aardvark.
Currently, persisted log messages contain a date, text, type, and optionally an image. The ARKLogMessage
class also has a userInfo
dictionary that contains contextual information for log observers, but this is not persisted.
We should add a parameters
dictionary used to store consumer-defined key/value pairs that don't have their own properties. Unlike the userInfo
, this dictionary will be persisted. This makes it possible to store richer log messages without having to parse the textualized message later.
The ARKDefaultLogFormatter
should also be updated to include these parameters in its formatting, e.g.:
Log message
- key1: value1
- key2: value2
Steps: (I used aardvark sample app)
Things work again after restart
This will make bug reporting all the more useful when using overlays and layered windows.
Apple has an example on how to composite a screenshot in UIKit: http://web.archive.org/web/20100725234258/http://developer.apple.com/iphone/library/qa/qa2010/qa1703.html (thanks @natan for the link!)
We'd likely want to just adopt that code in logScreenshot
Hit this crash last night on iOS 9 while trying to file a bug:
Thread : Fatal Exception: CALayerInvalidGeometry β sublayer with non-finite position [inf inf]
0 CoreFoundation 0x00000001826dcf5c __exceptionPreprocess
1 libobjc.A.dylib 0x00000001972cff80 objc_exception_throw
2 CoreFoundation 0x00000001826dcea4 -[NSException initWithCoder:]
3 QuartzCore 0x0000000187481a94 -[CALayer _renderSublayersInContext:]
4 QuartzCore 0x0000000187480ac0 -[CALayer renderInContext:]
5 QuartzCore 0x0000000187481a60 -[CALayer _renderSublayersInContext:]
6 QuartzCore 0x0000000187480ac0 -[CALayer renderInContext:]
7 QuartzCore 0x0000000187481a60 -[CALayer _renderSublayersInContext:]
8 QuartzCore 0x0000000187480ac0 -[CALayer renderInContext:]
9 QuartzCore 0x0000000187481a60 -[CALayer _renderSublayersInContext:]
10 QuartzCore 0x0000000187480ac0 -[CALayer renderInContext:]
11 QuartzCore 0x0000000187481a60 -[CALayer _renderSublayersInContext:]
12 QuartzCore 0x0000000187480ac0 -[CALayer renderInContext:]
13 Cash 0x00000001002d7b8c -[ARKLogDistributor logScreenshot] (ARKLogDistributor.m:249)
14 Cash 0x00000001002dc8d4 ARKLogScreenshot (Aardvark.m:49)
15 Cash 0x00000001002d2f48 -[ARKEmailBugReporter composeBugReport] (ARKEmailBugReporter.m:100)
16 Cash 0x00000001002dde24 -[UIApplication(ARKAdditions) _ARK_didFireBugReportGestureRecognizer:] (UIApplication+ARKAdditions.m:105)
17 UIKit 0x000000018818bb28 _UIGestureRecognizerSendTargetActions
18 UIKit 0x0000000187dd2a5c _UIGestureRecognizerSendActions
19 UIKit 0x0000000187c656ac -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:]
20 UIKit 0x000000018818ce78 ___UIGestureRecognizerUpdate_block_invoke809
21 UIKit 0x0000000187c25118 _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks
22 UIKit 0x0000000187c231ec _UIGestureRecognizerUpdate
23 CoreFoundation 0x0000000182693c30 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
24 CoreFoundation 0x00000001826919d4 __CFRunLoopDoObservers
25 CoreFoundation 0x0000000182691e04 __CFRunLoopRun
26 CoreFoundation 0x00000001825c0dc0 CFRunLoopRunSpecific
27 GraphicsServices 0x000000018d714088 GSEventRunModal
28 UIKit 0x0000000187c9af60 UIApplicationMain
29 Cash 0x00000001002c3d80 main (main.mm:28)
30 libdyld.dylib 0x0000000197afa8b8 start
Likely a layout bug in the app or iOS 9 β a layer with an infinite size is odd, to say the least. Looking into this today. Plan is to try/catch logging the screenshot so we don't crash on bug-file. I'll also look into whether there are other screen capture mechanisms we could use (short of requiring camera roll access).
This crash was reliably reproducible on one screen in my app. Was not reproducible in other screens.
Xcode 12 drops support for iOS 8. Release a new version that targets iOS 9+.
From the Xcode 12 Beta Release Notes:
Xcode 12 beta 5 includes SDKs for iOS 14, iPadOS 14, tvOS 14, watchOS 7, and macOS 11. The Xcode 12 beta 5 release supports on-device debugging for iOS 9 and later, tvOS 9 and later, and watchOS 2 and later. Xcode 12 beta 5 requires Apple silicon running macOS Big Sur 11 beta or later, or an Intel-based Mac running macOS Catalina 10.15.4 or later.
In Aardvark 2, persistedLogFileURL
was a public API on ARKLogStore
which allowed subclasses to override things and redirect logs to a custom destination, e.g. outside of app support or to a subfolder of app support
In Aardvark 3, persistedLogFileURL
was made internal to ARKLogStore
which means that subclasses need to redeclare private properties and make a new ARKDataArchive
in order to continue to redirect logs
It would be great if Aardvark had an initializer or other API that allowed for the log file path to be customized without the need to subclass things!
See #92 (comment)
Raised this issue here: #34
Similar to the ARKEmailBugReporterEmailBodyAdditionsDelegate
, we should add an ARKEmailBugReporterEmailAttachmentsDelegate
that allows additions/filtering of attached files. This makes it possible to include more app-specific data to bug reports and to filter out default attachments based on context.
macOs Big Sur 11.4
Xcode 12.5 (Intel)
Aardvark/4.0.0
Carthage/Checkouts/Aardvark/Sources/CoreAardvark/Logging/ARKExceptionLogging.m:36:52: error: this old-style function definition is not preceded by a prototype [-Werror,-Wstrict-prototypes] NSLock * ARKGetUncaughtExceptionLogDistributorsLock()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.