Skip to content

Remove the logging of GaugeMetadata to allow using AQS #6678

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

Merged
merged 5 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ public static FirebasePerformance getInstance() {
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider);

Context appContext = firebaseApp.getApplicationContext();
// TODO(b/110178816): Explore moving off of main thread.
mMetadataBundle = extractMetadata(appContext);

remoteConfigManager.setFirebaseRemoteConfigProvider(firebaseRemoteConfigProvider);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,13 @@ public SessionManager(
* (currently that is before onResume finishes) to ensure gauge collection starts on time.
*/
public void setApplicationContext(final Context appContext) {
// Get PerfSession in main thread first, because it is possible that app changes fg/bg state
// which creates a new perfSession, before the following is executed in background thread
final PerfSession appStartSession = perfSession;
// TODO(b/258263016): Migrate to go/firebase-android-executors
@SuppressLint("ThreadPoolCreation")
ExecutorService executorService = Executors.newSingleThreadExecutor();
syncInitFuture =
executorService.submit(
() -> {
gaugeManager.initializeGaugeMetadataManager(appContext);
if (appStartSession.isGaugeAndEventCollectionEnabled()) {
gaugeManager.logGaugeMetadata(
appStartSession.sessionId(), ApplicationProcessState.FOREGROUND);
}
});
}

Expand Down Expand Up @@ -164,9 +157,6 @@ public void updatePerfSession(PerfSession perfSession) {
}
}

// Log the gauge metadata event if data collection is enabled.
logGaugeMetadataIfCollectionEnabled(appStateMonitor.getAppState());

// Start of stop the gauge data collection.
startOrStopCollectingGauges(appStateMonitor.getAppState());
}
Expand All @@ -178,7 +168,6 @@ public void updatePerfSession(PerfSession perfSession) {
* this does not reset the perfSession.
*/
public void initializeGaugeCollection() {
logGaugeMetadataIfCollectionEnabled(ApplicationProcessState.FOREGROUND);
startOrStopCollectingGauges(ApplicationProcessState.FOREGROUND);
}

Expand Down Expand Up @@ -206,12 +195,6 @@ public void unregisterForSessionUpdates(WeakReference<SessionAwareObject> client
}
}

private void logGaugeMetadataIfCollectionEnabled(ApplicationProcessState appState) {
if (perfSession.isGaugeAndEventCollectionEnabled()) {
gaugeManager.logGaugeMetadata(perfSession.sessionId(), appState);
}
}

private void startOrStopCollectingGauges(ApplicationProcessState appState) {
if (perfSession.isGaugeAndEventCollectionEnabled()) {
gaugeManager.startCollectingGauges(perfSession, appState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
import static android.system.Os.sysconf;

import android.annotation.SuppressLint;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.system.OsConstants;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
Expand Down Expand Up @@ -163,7 +161,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate(
this.cpuMetricCollectionRateMs = cpuMetricCollectionRate;
try {
cpuMetricCollectorJob =
cpuMetricCollectorExecutor.scheduleAtFixedRate(
cpuMetricCollectorExecutor.scheduleWithFixedDelay(
() -> {
CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime);
if (currCpuReading != null) {
Expand All @@ -181,7 +179,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate(
private synchronized void scheduleCpuMetricCollectionOnce(Timer referenceTime) {
try {
@SuppressWarnings("FutureReturnValueIgnored")
ScheduledFuture unusedFuture =
ScheduledFuture<?> unusedFuture =
cpuMetricCollectorExecutor.schedule(
() -> {
CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime);
Expand Down Expand Up @@ -227,12 +225,7 @@ private CpuMetricReading syncCollectCpuMetric(Timer referenceTime) {
}

private long getClockTicksPerSecond() {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
return sysconf(OsConstants._SC_CLK_TCK);
} else {
// TODO(b/110779408): Figure out how to collect this info for Android API 20 and below.
return INVALID_SC_PER_CPU_CLOCK_TICK;
}
return sysconf(OsConstants._SC_CLK_TCK);
}

private long convertClockTicksToMicroseconds(long clockTicks) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ private GaugeManager() {
TransportManager.getInstance(),
ConfigResolver.getInstance(),
null,
new Lazy<>(() -> new CpuGaugeCollector()),
new Lazy<>(() -> new MemoryGaugeCollector()));
new Lazy<>(CpuGaugeCollector::new),
new Lazy<>(MemoryGaugeCollector::new));
}

@VisibleForTesting
GaugeManager(
Lazy<ScheduledExecutorService> gaugeManagerExecutor,
TransportManager transportManager,
ConfigResolver configResolver,
GaugeMetadataManager gaugeMetadataManager,
@Nullable GaugeMetadataManager gaugeMetadataManager,
Lazy<CpuGaugeCollector> cpuGaugeCollector,
Lazy<MemoryGaugeCollector> memoryGaugeCollector) {

Expand Down Expand Up @@ -140,7 +140,7 @@ public void startCollectingGauges(
gaugeManagerDataCollectionJob =
gaugeManagerExecutor
.get()
.scheduleAtFixedRate(
.scheduleWithFixedDelay(
() -> {
syncFlush(sessionIdForScheduledTask, applicationProcessStateForScheduledTask);
},
Expand Down Expand Up @@ -256,6 +256,7 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
* @return true if GaugeMetadata was logged, false otherwise.
*/
public boolean logGaugeMetadata(String sessionId, ApplicationProcessState appState) {
// TODO(b/394127311): Re-introduce logging of metadata for AQS.
if (gaugeMetadataManager != null) {
GaugeMetric gaugeMetric =
GaugeMetric.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,11 @@
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.content.Context;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.VisibleForTesting;
import com.google.firebase.perf.logging.AndroidLogger;
import com.google.firebase.perf.util.StorageUnit;
import com.google.firebase.perf.util.Utils;
import com.google.firebase.perf.v1.GaugeMetadata;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* The {@code GaugeMetadataManager} class is responsible for collecting {@link GaugeMetadata}
Expand All @@ -41,7 +34,6 @@ class GaugeMetadataManager {
private final Runtime runtime;
private final ActivityManager activityManager;
private final MemoryInfo memoryInfo;
private final Context appContext;

GaugeMetadataManager(Context appContext) {
this(Runtime.getRuntime(), appContext);
Expand All @@ -50,7 +42,6 @@ class GaugeMetadataManager {
@VisibleForTesting
GaugeMetadataManager(Runtime runtime, Context appContext) {
this.runtime = runtime;
this.appContext = appContext;
this.activityManager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
Expand All @@ -75,29 +66,6 @@ public int getMaxEncouragedAppJavaHeapMemoryKb() {

/** Returns the total memory (in kilobytes) accessible by the kernel (called the RAM size). */
public int getDeviceRamSizeKb() {
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem));
}

return readTotalRAM(/* procFileName= */ "/proc/meminfo");
}

/** Returns the total ram size of the device (in kilobytes) by reading the "proc/meminfo" file. */
@VisibleForTesting
int readTotalRAM(String procFileName) {
try (BufferedReader br = new BufferedReader(new FileReader(procFileName))) {
for (String s = br.readLine(); s != null; s = br.readLine()) {
if (s.startsWith("MemTotal")) {
Matcher m = Pattern.compile("\\d+").matcher(s);
return m.find() ? Integer.parseInt(m.group()) : 0;
}
}
} catch (IOException ioe) {
logger.warn("Unable to read '" + procFileName + "' file: " + ioe.getMessage());
} catch (NumberFormatException nfe) {
logger.warn("Unable to parse '" + procFileName + "' file: " + nfe.getMessage());
}

return 0;
return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class MemoryGaugeCollector {
public final ConcurrentLinkedQueue<AndroidMemoryReading> memoryMetricReadings;
private final Runtime runtime;

@Nullable private ScheduledFuture memoryMetricCollectorJob = null;
@Nullable private ScheduledFuture<?> memoryMetricCollectorJob = null;
private long memoryMetricCollectionRateMs = UNSET_MEMORY_METRIC_COLLECTION_RATE;

// TODO(b/258263016): Migrate to go/firebase-android-executors
Expand Down Expand Up @@ -124,7 +124,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate(

try {
memoryMetricCollectorJob =
memoryMetricCollectorExecutor.scheduleAtFixedRate(
memoryMetricCollectorExecutor.scheduleWithFixedDelay(
() -> {
AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime);
if (memoryReading != null) {
Expand All @@ -142,7 +142,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate(
private synchronized void scheduleMemoryMetricCollectionOnce(Timer referenceTime) {
try {
@SuppressWarnings("FutureReturnValueIgnored")
ScheduledFuture unusedFuture =
ScheduledFuture<?> unusedFuture =
memoryMetricCollectorExecutor.schedule(
() -> {
AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void testInstanceCreation() {
}

@Test
public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsInitialized()
public void setApplicationContext_initializeGaugeMetadataManager()
throws ExecutionException, InterruptedException {
when(mockPerfSession.isGaugeAndEventCollectionEnabled()).thenReturn(true);
InOrder inOrder = Mockito.inOrder(mockGaugeManager);
Expand All @@ -84,7 +84,6 @@ public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsIn

testSessionManager.getSyncInitFuture().get();
inOrder.verify(mockGaugeManager).initializeGaugeMetadataManager(any());
inOrder.verify(mockGaugeManager).logGaugeMetadata(any(), any());
}

@Test
Expand Down Expand Up @@ -136,20 +135,6 @@ public void testOnUpdateAppStateGeneratesNewSessionIdOnBackgroundStateIfPerfSess
assertThat(oldSessionId).isNotEqualTo(testSessionManager.perfSession().sessionId());
}

@Test
public void
testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsVerbose() {
forceVerboseSession();

SessionManager testSessionManager =
new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor);
testSessionManager.onUpdateAppState(ApplicationProcessState.FOREGROUND);

verify(mockGaugeManager)
.logGaugeMetadata(
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
}

@Test
public void
testOnUpdateAppStateDoesntMakeGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsNonVerbose() {
Expand Down Expand Up @@ -178,21 +163,6 @@ public void testOnUpdateAppStateGeneratesNewSessionIdOnBackgroundStateIfPerfSess
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
}

@Test
public void
testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnBackgroundAppStateIfSessionIsVerboseAndTimedOut() {
when(mockPerfSession.isSessionRunningTooLong()).thenReturn(true);
forceVerboseSession();

SessionManager testSessionManager =
new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor);
testSessionManager.onUpdateAppState(ApplicationProcessState.BACKGROUND);

verify(mockGaugeManager)
.logGaugeMetadata(
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
}

@Test
public void testOnUpdateAppStateMakesGaugeManagerStartCollectingGaugesIfSessionIsVerbose() {
forceVerboseSession();
Expand Down Expand Up @@ -232,32 +202,6 @@ public void testOnUpdateAppStateMakesGaugeManagerStopCollectingGaugesWhenSession
verify(mockGaugeManager).stopCollectingGauges();
}

@Test
public void testGaugeMetadataIsFlushedOnlyWhenNewVerboseSessionIsCreated() {
when(mockPerfSession.isSessionRunningTooLong()).thenReturn(false);

// Start with a non verbose session
forceNonVerboseSession();
SessionManager testSessionManager =
new SessionManager(
mockGaugeManager, PerfSession.createWithId("testSessionId1"), mockAppStateMonitor);

verify(mockGaugeManager, times(0))
.logGaugeMetadata(
eq("testSessionId1"),
eq(com.google.firebase.perf.v1.ApplicationProcessState.FOREGROUND));

// Forcing a verbose session will enable Gauge collection
forceVerboseSession();
testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2"));
verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId2"), any());

// Force a non-verbose session and verify if we are not logging metadata
forceVerboseSession();
testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId3"));
verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId3"), any());
}

@Test
public void testSessionIdDoesNotUpdateIfPerfSessionRunsTooLong() {
Timer mockTimer = mock(Timer.class);
Expand Down
Loading
Loading