Skip to content

Commit 504c065

Browse files
authored
Update GaugeManager for AQS (#6938)
- Update Gauge metrics collection frequency to be independent of Session Change. - Update GaugeMetric logging to log them based on metrics count - Necessary changes in SessionManager (remove app state monitor) There's a non-trivial number of unit test failures in GaugeManager. This PR marks them as Ignore with a TODO.
1 parent ea80eb1 commit 504c065

File tree

13 files changed

+213
-162
lines changed

13 files changed

+213
-162
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/metrics/NetworkRequestMetricBuilder.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public NetworkRequestMetricBuilder setCustomAttributes(Map<String, String> attri
224224
* point depending upon the current {@link PerfSession} verbosity.
225225
*
226226
* @see GaugeManager#collectGaugeMetricOnce(Timer)
227-
* @see PerfSession#isGaugeAndEventCollectionEnabled()
227+
* @see PerfSession#isVerbose()
228228
*/
229229
public NetworkRequestMetricBuilder setRequestStartTimeMicros(long time) {
230230
SessionManager sessionManager = SessionManager.getInstance();
@@ -234,7 +234,7 @@ public NetworkRequestMetricBuilder setRequestStartTimeMicros(long time) {
234234
builder.setClientStartTimeUs(time);
235235
updateSession(perfSession);
236236

237-
if (perfSession.isGaugeAndEventCollectionEnabled()) {
237+
if (perfSession.isVerbose()) {
238238
gaugeManager.collectGaugeMetricOnce(perfSession.getTimer());
239239
}
240240

@@ -265,12 +265,12 @@ public long getTimeToResponseInitiatedMicros() {
265265
* point depending upon the current {@link PerfSession} Verbosity.
266266
*
267267
* @see GaugeManager#collectGaugeMetricOnce(Timer)
268-
* @see PerfSession#isGaugeAndEventCollectionEnabled()
268+
* @see PerfSession#isVerbose()
269269
*/
270270
public NetworkRequestMetricBuilder setTimeToResponseCompletedMicros(long time) {
271271
builder.setTimeToResponseCompletedUs(time);
272272

273-
if (SessionManager.getInstance().perfSession().isGaugeAndEventCollectionEnabled()) {
273+
if (SessionManager.getInstance().perfSession().isVerbose()) {
274274
gaugeManager.collectGaugeMetricOnce(SessionManager.getInstance().perfSession().getTimer());
275275
}
276276

firebase-perf/src/main/java/com/google/firebase/perf/metrics/Trace.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public void start() {
233233

234234
updateSession(perfSession);
235235

236-
if (perfSession.isGaugeAndEventCollectionEnabled()) {
236+
if (perfSession.isVerbose()) {
237237
gaugeManager.collectGaugeMetricOnce(perfSession.getTimer());
238238
}
239239
}
@@ -259,7 +259,7 @@ public void stop() {
259259
if (!name.isEmpty()) {
260260
transportManager.log(new TraceMetricBuilder(this).build(), getAppState());
261261

262-
if (SessionManager.getInstance().perfSession().isGaugeAndEventCollectionEnabled()) {
262+
if (SessionManager.getInstance().perfSession().isVerbose()) {
263263
gaugeManager.collectGaugeMetricOnce(
264264
SessionManager.getInstance().perfSession().getTimer());
265265
}

firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java

+11-17
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,15 @@ public static PerfSession createWithId(@Nullable String aqsSessionId) {
4040
if (sessionId == null) {
4141
sessionId = FirebaseSessionsHelperKt.createLegacySessionId();
4242
}
43-
PerfSession session = new PerfSession(sessionId, new Clock());
44-
session.setGaugeAndEventCollectionEnabled(session.shouldCollectGaugesAndEvents());
45-
return session;
43+
return new PerfSession(sessionId, new Clock());
4644
}
4745

4846
/** Creates a PerfSession with the provided {@code sessionId} and {@code clock}. */
4947
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
5048
public PerfSession(String sessionId, Clock clock) {
5149
this.sessionId = sessionId;
5250
creationTime = clock.getTime();
51+
isGaugeAndEventCollectionEnabled = shouldCollectGaugesAndEvents();
5352
}
5453

5554
private PerfSession(@NonNull Parcel in) {
@@ -72,20 +71,6 @@ public Timer getTimer() {
7271
return creationTime;
7372
}
7473

75-
/*
76-
* Enables/Disables the gauge and event collection for the system.
77-
*/
78-
public void setGaugeAndEventCollectionEnabled(boolean enabled) {
79-
isGaugeAndEventCollectionEnabled = enabled;
80-
}
81-
82-
/*
83-
* Returns if gauge and event collection is enabled for the system.
84-
*/
85-
public boolean isGaugeAndEventCollectionEnabled() {
86-
return isGaugeAndEventCollectionEnabled;
87-
}
88-
8974
/** Returns if the current session is verbose or not. */
9075
public boolean isVerbose() {
9176
return isGaugeAndEventCollectionEnabled;
@@ -152,13 +137,22 @@ public static com.google.firebase.perf.v1.PerfSession[] buildAndSort(
152137
}
153138

154139
/** If true, Session Gauge collection is enabled. */
140+
@VisibleForTesting
155141
public boolean shouldCollectGaugesAndEvents() {
156142
ConfigResolver configResolver = ConfigResolver.getInstance();
157143
return configResolver.isPerformanceMonitoringEnabled()
158144
&& (Math.abs(this.sessionId.hashCode() % 100)
159145
< configResolver.getSessionsSamplingRate() * 100);
160146
}
161147

148+
/*
149+
* Enables/Disables whether the session is verbose or not.
150+
*/
151+
@VisibleForTesting
152+
public void setGaugeAndEventCollectionEnabled(boolean enabled) {
153+
isGaugeAndEventCollectionEnabled = enabled;
154+
}
155+
162156
/**
163157
* Describes the kinds of special objects contained in this Parcelable's marshalled
164158
* representation. Please refer to

firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java

+10-18
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@
1818
import android.content.Context;
1919
import androidx.annotation.Keep;
2020
import androidx.annotation.VisibleForTesting;
21-
import com.google.firebase.perf.application.AppStateMonitor;
2221
import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck;
2322
import com.google.firebase.perf.session.gauges.GaugeManager;
24-
import com.google.firebase.perf.v1.ApplicationProcessState;
2523
import com.google.firebase.perf.v1.GaugeMetadata;
2624
import com.google.firebase.perf.v1.GaugeMetric;
2725
import java.lang.ref.WeakReference;
@@ -37,7 +35,6 @@ public class SessionManager {
3735
private static final SessionManager instance = new SessionManager();
3836

3937
private final GaugeManager gaugeManager;
40-
private final AppStateMonitor appStateMonitor;
4138
private final Set<WeakReference<SessionAwareObject>> clients = new HashSet<>();
4239

4340
private PerfSession perfSession;
@@ -49,23 +46,20 @@ public static SessionManager getInstance() {
4946

5047
/** Returns the currently active PerfSession. */
5148
public final PerfSession perfSession() {
52-
FirebaseSessionsEnforcementCheck.checkSession(
53-
perfSession, "Access perf session from manger without aqs ready");
49+
FirebaseSessionsEnforcementCheck.checkSession(perfSession, "PerfSession.perfSession()");
5450

5551
return perfSession;
5652
}
5753

5854
private SessionManager() {
5955
// session should quickly updated by session subscriber.
60-
this(GaugeManager.getInstance(), PerfSession.createWithId(null), AppStateMonitor.getInstance());
56+
this(GaugeManager.getInstance(), PerfSession.createWithId(null));
6157
}
6258

6359
@VisibleForTesting
64-
public SessionManager(
65-
GaugeManager gaugeManager, PerfSession perfSession, AppStateMonitor appStateMonitor) {
60+
public SessionManager(GaugeManager gaugeManager, PerfSession perfSession) {
6661
this.gaugeManager = gaugeManager;
6762
this.perfSession = perfSession;
68-
this.appStateMonitor = appStateMonitor;
6963
}
7064

7165
/**
@@ -83,8 +77,7 @@ public void setApplicationContext(final Context appContext) {
8377
*/
8478
public void stopGaugeCollectionIfSessionRunningTooLong() {
8579
FirebaseSessionsEnforcementCheck.checkSession(
86-
perfSession,
87-
"Session is not ready while trying to stopGaugeCollectionIfSessionRunningTooLong");
80+
perfSession, "SessionManager.stopGaugeCollectionIfSessionRunningTooLong");
8881

8982
if (perfSession.isSessionRunningTooLong()) {
9083
gaugeManager.stopCollectingGauges();
@@ -123,7 +116,7 @@ public void updatePerfSession(PerfSession perfSession) {
123116
}
124117

125118
// Start of stop the gauge data collection.
126-
startOrStopCollectingGauges(appStateMonitor.getAppState());
119+
startOrStopCollectingGauges();
127120
}
128121

129122
/**
@@ -133,7 +126,7 @@ public void updatePerfSession(PerfSession perfSession) {
133126
* this does not reset the perfSession.
134127
*/
135128
public void initializeGaugeCollection() {
136-
startOrStopCollectingGauges(ApplicationProcessState.FOREGROUND);
129+
startOrStopCollectingGauges();
137130
}
138131

139132
/**
@@ -160,12 +153,11 @@ public void unregisterForSessionUpdates(WeakReference<SessionAwareObject> client
160153
}
161154
}
162155

163-
private void startOrStopCollectingGauges(ApplicationProcessState appState) {
164-
FirebaseSessionsEnforcementCheck.checkSession(
165-
perfSession, "Session is not ready while trying to startOrStopCollectingGauges");
156+
private void startOrStopCollectingGauges() {
157+
FirebaseSessionsEnforcementCheck.checkSession(perfSession, "startOrStopCollectingGauges");
166158

167-
if (perfSession.isGaugeAndEventCollectionEnabled()) {
168-
gaugeManager.startCollectingGauges(perfSession, appState);
159+
if (perfSession.isVerbose()) {
160+
gaugeManager.startCollectingGauges(perfSession);
169161
} else {
170162
gaugeManager.stopCollectingGauges();
171163
}

firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/CpuGaugeCollector.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public class CpuGaugeCollector {
7676
private final String procFileName;
7777
private final long clockTicksPerSecond;
7878

79-
@Nullable private ScheduledFuture cpuMetricCollectorJob = null;
79+
@Nullable private ScheduledFuture<?> cpuMetricCollectorJob = null;
8080
private long cpuMetricCollectionRateMs = UNSET_CPU_METRIC_COLLECTION_RATE;
8181

8282
// TODO(b/258263016): Migrate to go/firebase-android-executors
@@ -166,6 +166,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate(
166166
CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime);
167167
if (currCpuReading != null) {
168168
cpuMetricReadings.add(currCpuReading);
169+
GaugeCounter.INSTANCE.incrementCounter();
169170
}
170171
},
171172
/* initialDelay */ 0,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.perf.session.gauges
16+
17+
import java.util.concurrent.atomic.AtomicInteger
18+
19+
/**
20+
* [GaugeCounter] is a thread-safe counter for gauge metrics. If the metrics count exceeds
21+
* [MAX_METRIC_COUNT], it attempts to log the metrics to Firelog.
22+
*/
23+
object GaugeCounter {
24+
private const val MAX_METRIC_COUNT = 25
25+
private val counter = AtomicInteger(0)
26+
private val gaugeManager: GaugeManager = GaugeManager.getInstance()
27+
28+
fun incrementCounter() {
29+
val metricsCount = counter.incrementAndGet()
30+
31+
if (metricsCount >= MAX_METRIC_COUNT) {
32+
gaugeManager.logGaugeMetrics()
33+
}
34+
}
35+
36+
fun decrementCounter() {
37+
counter.decrementAndGet()
38+
}
39+
}

0 commit comments

Comments
 (0)