-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract ANR detection instrumentation (#399)
* Extract ANR detection instrumentation * Code review comments
- Loading branch information
Mateusz Rzeszutek
authored
Nov 4, 2022
1 parent
eb439e9
commit 0af808d
Showing
13 changed files
with
487 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
...-android/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright Splunk Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.opentelemetry.rum.internal.instrumentation.anr; | ||
|
||
import android.os.Handler; | ||
import android.os.Looper; | ||
import io.opentelemetry.api.OpenTelemetry; | ||
import io.opentelemetry.api.trace.StatusCode; | ||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; | ||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; | ||
import io.opentelemetry.rum.internal.instrumentation.InstrumentedApplication; | ||
import java.util.List; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
|
||
/** Entrypoint for installing the ANR (application not responding) detection instrumentation. */ | ||
public final class AnrDetector { | ||
|
||
/** Returns a new {@link AnrDetector} with the default settings. */ | ||
public static AnrDetector create() { | ||
return builder().build(); | ||
} | ||
|
||
/** Returns a new {@link AnrDetectorBuilder}. */ | ||
public static AnrDetectorBuilder builder() { | ||
return new AnrDetectorBuilder(); | ||
} | ||
|
||
private final List<AttributesExtractor<StackTraceElement[], Void>> additionalExtractors; | ||
private final Looper mainLooper; | ||
private final ScheduledExecutorService scheduler; | ||
|
||
AnrDetector(AnrDetectorBuilder builder) { | ||
this.additionalExtractors = builder.additionalExtractors; | ||
this.mainLooper = builder.mainLooper; | ||
this.scheduler = builder.scheduler; | ||
} | ||
|
||
/** | ||
* Installs the ANR detection instrumentation on the given {@link InstrumentedApplication}. | ||
* | ||
* <p>When the main thread is unresponsive for 5 seconds or more, an event including the main | ||
* thread's stack trace will be reported to the RUM system. | ||
*/ | ||
public void installOn(InstrumentedApplication instrumentedApplication) { | ||
Handler uiHandler = new Handler(mainLooper); | ||
AnrWatcher anrWatcher = | ||
new AnrWatcher( | ||
uiHandler, | ||
mainLooper.getThread(), | ||
buildAnrInstrumenter(instrumentedApplication.getOpenTelemetrySdk())); | ||
|
||
AnrDetectorToggler listener = new AnrDetectorToggler(anrWatcher, scheduler); | ||
// call it manually the first time to enable the ANR detection | ||
listener.onApplicationForegrounded(); | ||
|
||
instrumentedApplication.registerApplicationStateListener(listener); | ||
} | ||
|
||
private Instrumenter<StackTraceElement[], Void> buildAnrInstrumenter( | ||
OpenTelemetry openTelemetry) { | ||
return Instrumenter.<StackTraceElement[], Void>builder( | ||
openTelemetry, "io.opentelemetry.anr", stackTrace -> "ANR") | ||
// it's always an error | ||
.setSpanStatusExtractor( | ||
(spanStatusBuilder, stackTrace, unused, error) -> | ||
spanStatusBuilder.setStatus(StatusCode.ERROR)) | ||
.addAttributesExtractor(new StackTraceFormatter()) | ||
.addAttributesExtractors(additionalExtractors) | ||
.buildInstrumenter(); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...d/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Copyright Splunk Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.opentelemetry.rum.internal.instrumentation.anr; | ||
|
||
import android.os.Looper; | ||
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
|
||
/** A builder of {@link AnrDetector}. */ | ||
public final class AnrDetectorBuilder { | ||
|
||
AnrDetectorBuilder() {} | ||
|
||
final List<AttributesExtractor<StackTraceElement[], Void>> additionalExtractors = | ||
new ArrayList<>(); | ||
Looper mainLooper = Looper.getMainLooper(); | ||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); | ||
|
||
/** Adds an {@link AttributesExtractor} that will extract additional attributes. */ | ||
public AnrDetectorBuilder addAttributesExtractor( | ||
AttributesExtractor<StackTraceElement[], Void> extractor) { | ||
additionalExtractors.add(extractor); | ||
return this; | ||
} | ||
|
||
/** Sets a custom {@link Looper} to run on. Useful for testing. */ | ||
public AnrDetectorBuilder setMainLooper(Looper looper) { | ||
mainLooper = looper; | ||
return this; | ||
} | ||
|
||
// visible for tests | ||
AnrDetectorBuilder setScheduler(ScheduledExecutorService scheduler) { | ||
this.scheduler = scheduler; | ||
return this; | ||
} | ||
|
||
/** Returns a new {@link AnrDetector} with the settings of this {@link AnrDetectorBuilder}. */ | ||
public AnrDetector build() { | ||
return new AnrDetector(this); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
...d/src/main/java/io/opentelemetry/rum/internal/instrumentation/anr/AnrDetectorToggler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright Splunk Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.opentelemetry.rum.internal.instrumentation.anr; | ||
|
||
import androidx.annotation.Nullable; | ||
import io.opentelemetry.rum.internal.instrumentation.ApplicationStateListener; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.ScheduledFuture; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
final class AnrDetectorToggler implements ApplicationStateListener { | ||
|
||
private final Runnable anrWatcher; | ||
private final ScheduledExecutorService anrScheduler; | ||
|
||
@Nullable private ScheduledFuture<?> future; | ||
|
||
AnrDetectorToggler(Runnable anrWatcher, ScheduledExecutorService anrScheduler) { | ||
this.anrWatcher = anrWatcher; | ||
this.anrScheduler = anrScheduler; | ||
} | ||
|
||
@Override | ||
public void onApplicationForegrounded() { | ||
if (future == null) { | ||
future = anrScheduler.scheduleAtFixedRate(anrWatcher, 1, 1, TimeUnit.SECONDS); | ||
} | ||
} | ||
|
||
@Override | ||
public void onApplicationBackgrounded() { | ||
if (future != null) { | ||
future.cancel(true); | ||
future = null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.