Skip to content

Expose Telemetry and addLongTask for internal use#983

Merged
fuzzybinary merged 5 commits into
developfrom
jward/expose-telemetry
Jul 15, 2022
Merged

Expose Telemetry and addLongTask for internal use#983
fuzzybinary merged 5 commits into
developfrom
jward/expose-telemetry

Conversation

@fuzzybinary

Copy link
Copy Markdown
Member

What does this PR do?

This exposes some internal Datadog classes and methods for use by cross platform frameworks.

We expose internal methods through the _InternalProxy class, which is documented for internal use, and the _internal static member on the Datadog object. We keep Telemetry and RUM as separate proxies, in case we have to split them as v2 takes shape.

As part of exposing telemetry I also needed a way to report errors that are not Throwable, so I modified the event to replace the throwable member with stack and kind, and moved the creation of those strings farther up the chain (they were created on event write prior).

Additional Notes

Please double check all my logic on the switch from throwable to stack and kind

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@fuzzybinary
fuzzybinary requested a review from a team as a code owner July 12, 2022 15:36
@fuzzybinary
fuzzybinary force-pushed the jward/expose-telemetry branch 3 times, most recently from 0041f01 to 121e55e Compare July 12, 2022 17:34
Comment on lines +333 to +338
var stack: String? = null
var kind: String? = null
throwable?.let {
stack = it.loggableStackTrace()
kind = it.javaClass.canonicalName ?: it.javaClass.simpleName
}
handleEvent(RumRawEvent.SendTelemetry(TelemetryType.ERROR, message, stack, kind))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
var stack: String? = null
var kind: String? = null
throwable?.let {
stack = it.loggableStackTrace()
kind = it.javaClass.canonicalName ?: it.javaClass.simpleName
}
handleEvent(RumRawEvent.SendTelemetry(TelemetryType.ERROR, message, stack, kind))
val stack: String? = throwable?.loggableStackTrace()
var kind: String? = throwable?.javaClass?.canonicalName ?: throwable?.javaClass?.simpleName
handleEvent(RumRawEvent.SendTelemetry(TelemetryType.ERROR, message, stack, kind))

@StringForgery kind: String
) {
// Given
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)
val proxy = _InternalProxy(rumMonitor.mockInstance)

@StringForgery message: String
) {
// Given
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)
val proxy = _InternalProxy(rumMonitor.mockInstance)

@StringForgery target: String
) {
// Given
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You shouldn't rely on static/global states in your tests.

Suggested change
val proxy = _InternalProxy(GlobalRum.get() as? AdvancedRumMonitor)
val proxy = _InternalProxy(rumMonitor.mockInstance)

)
class _InternalProxy {
class _TelemetryProxy {
private val telemetry: Telemetry = Telemetry()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we can also directly reference com.datadog.android.core.internal.utils.telemetry property I think (but in both cases the question of mocking for unit-tests arise).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Do you think we should inject Telemetry instead?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you can use default arguments in the constructor and provide them explicitly in the test.

*
* @see _InternalProxy
*/
@JvmStatic

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think we need this annotation here, because this property is supposed to be called only by us, so no interop with Java is needed (both Flutter and RN use Kotlin for the native modules).

@fuzzybinary
fuzzybinary requested review from 0xnm and xgouchet July 13, 2022 17:09
@fuzzybinary

Copy link
Copy Markdown
Member Author

Given some things we found in the iOS PR, I've restructured this to separate the "core" internals (only telemetry at the moment) and RUM Internals. This simplifies testing as well as avoids some issues with lazy initializers having unwelcome side affects.

@xgouchet xgouchet added the size-medium This PR is medium sized label Jul 13, 2022
@fuzzybinary
fuzzybinary force-pushed the jward/expose-telemetry branch from 660ef06 to 02e4afb Compare July 13, 2022 19:03
@codecov-commenter

codecov-commenter commented Jul 15, 2022

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.41935% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.98%. Comparing base (009bd1a) to head (2242bdb).
⚠️ Report is 3637 commits behind head on develop.

Files with missing lines Patch % Lines
.../android/rum/internal/monitor/DatadogRumMonitor.kt 42.86% 2 Missing and 2 partials ⚠️
.../main/kotlin/com/datadog/android/_InternalProxy.kt 88.89% 1 Missing ⚠️
...om/datadog/android/telemetry/internal/Telemetry.kt 0.00% 1 Missing ⚠️
...ndroid/telemetry/internal/TelemetryEventHandler.kt 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #983      +/-   ##
===========================================
- Coverage    83.08%   82.98%   -0.10%     
===========================================
  Files          268      270       +2     
  Lines         9218     9241      +23     
  Branches      1485     1486       +1     
===========================================
+ Hits          7658     7668      +10     
- Misses        1152     1162      +10     
- Partials       408      411       +3     
Files with missing lines Coverage Δ
...oid/src/main/kotlin/com/datadog/android/Datadog.kt 81.51% <100.00%> (+0.16%) ⬆️
.../main/kotlin/com/datadog/android/rum/RumMonitor.kt 77.78% <ø> (ø)
...otlin/com/datadog/android/rum/_RumInternalProxy.kt 100.00% <100.00%> (ø)
...g/android/rum/internal/domain/scope/RumRawEvent.kt 82.43% <100.00%> (+0.12%) ⬆️
.../main/kotlin/com/datadog/android/_InternalProxy.kt 88.89% <88.89%> (ø)
...om/datadog/android/telemetry/internal/Telemetry.kt 66.67% <0.00%> (-13.33%) ⬇️
...ndroid/telemetry/internal/TelemetryEventHandler.kt 91.94% <87.50%> (ø)
.../android/rum/internal/monitor/DatadogRumMonitor.kt 92.86% <42.86%> (-2.23%) ⬇️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@StringForgery message: String
) {
// Given
val mockTelemetry = Mockito.mock(Telemetry::class.java)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: we can do import org.mockito.Mockito.mock and just use mock call directly without Mockito. prefix as it is done in the codebase.

@StringForgery target: String
) {
// Given
val proxy = _RumInternalProxy(rumMonitor.mockInstance)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we can simply mock<AdvancedRumMonitor>() here, don't think we need to use GlobalRumMonitorTestConfiguration.

We expose internal methods through the _InternalProxy class, which is documented for internal use, and the `_internal` static member on the Datadog object. We keep Telemetry and RUM as separate proxies, in case we have to split them as v2 takes shape.

Exposing Telemetry requires adding a way for reporting errors that are not Throwable (for use in cross platform frameworks), so I modified the event to take `stack` and `kind` as strings instead.
@fuzzybinary
fuzzybinary force-pushed the jward/expose-telemetry branch from 043616a to 2242bdb Compare July 15, 2022 13:49
@fuzzybinary
fuzzybinary requested a review from 0xnm July 15, 2022 13:50
@fuzzybinary

Copy link
Copy Markdown
Member Author

@0xnm updated and rebased on develop for a final review.

@0xnm 0xnm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm!

@fuzzybinary
fuzzybinary merged commit 4fc552f into develop Jul 15, 2022
@fuzzybinary
fuzzybinary deleted the jward/expose-telemetry branch July 15, 2022 14:17
@xgouchet xgouchet added this to the 1.14.0 milestone Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-medium This PR is medium sized

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants