-
-
Notifications
You must be signed in to change notification settings - Fork 435
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feat/remove-sensitive-data-from-urls
- Loading branch information
Showing
48 changed files
with
1,153 additions
and
295 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
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
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
126 changes: 126 additions & 0 deletions
126
sentry-android-core/src/main/java/io/sentry/android/core/AndroidCpuCollector.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,126 @@ | ||
package io.sentry.android.core; | ||
|
||
import android.annotation.SuppressLint; | ||
import android.os.Build; | ||
import android.os.SystemClock; | ||
import android.system.Os; | ||
import android.system.OsConstants; | ||
import io.sentry.CpuCollectionData; | ||
import io.sentry.ICollector; | ||
import io.sentry.ILogger; | ||
import io.sentry.PerformanceCollectionData; | ||
import io.sentry.SentryLevel; | ||
import io.sentry.util.FileUtils; | ||
import io.sentry.util.Objects; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import org.jetbrains.annotations.ApiStatus; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
// The approach to get the cpu usage info was taken from | ||
// https://eng.lyft.com/monitoring-cpu-performance-of-lyfts-android-applications-4e36fafffe12 | ||
// The content of the /proc/self/stat file is specified in | ||
// https://man7.org/linux/man-pages/man5/proc.5.html | ||
@ApiStatus.Internal | ||
public final class AndroidCpuCollector implements ICollector { | ||
|
||
private long lastRealtimeNanos = 0; | ||
private long lastCpuNanos = 0; | ||
|
||
/** Number of clock ticks per second. */ | ||
private long clockSpeedHz = 1; | ||
|
||
private long numCores = 1; | ||
private final long NANOSECOND_PER_SECOND = 1_000_000_000; | ||
|
||
/** Number of nanoseconds per clock tick. */ | ||
private double nanosecondsPerClockTick = NANOSECOND_PER_SECOND / (double) clockSpeedHz; | ||
|
||
/** File containing stats about this process. */ | ||
private final @NotNull File selfStat = new File("/proc/self/stat"); | ||
|
||
private final @NotNull ILogger logger; | ||
private final @NotNull BuildInfoProvider buildInfoProvider; | ||
private boolean isEnabled = false; | ||
|
||
public AndroidCpuCollector( | ||
final @NotNull ILogger logger, final @NotNull BuildInfoProvider buildInfoProvider) { | ||
this.logger = Objects.requireNonNull(logger, "Logger is required."); | ||
this.buildInfoProvider = | ||
Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required."); | ||
} | ||
|
||
@SuppressLint("NewApi") | ||
@Override | ||
public void setup() { | ||
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP) { | ||
isEnabled = false; | ||
return; | ||
} | ||
isEnabled = true; | ||
clockSpeedHz = Os.sysconf(OsConstants._SC_CLK_TCK); | ||
numCores = Os.sysconf(OsConstants._SC_NPROCESSORS_CONF); | ||
nanosecondsPerClockTick = NANOSECOND_PER_SECOND / (double) clockSpeedHz; | ||
lastCpuNanos = readTotalCpuNanos(); | ||
} | ||
|
||
@SuppressLint("NewApi") | ||
@Override | ||
public void collect( | ||
@NotNull final Iterable<PerformanceCollectionData> performanceCollectionData) { | ||
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP || !isEnabled) { | ||
return; | ||
} | ||
final long nowNanos = SystemClock.elapsedRealtimeNanos(); | ||
final long realTimeNanosDiff = nowNanos - lastRealtimeNanos; | ||
lastRealtimeNanos = nowNanos; | ||
final long cpuNanos = readTotalCpuNanos(); | ||
final long cpuNanosDiff = cpuNanos - lastCpuNanos; | ||
lastCpuNanos = cpuNanos; | ||
// Later we need to divide the percentage by the number of cores, otherwise we could | ||
// get a percentage value higher than 1. We also want to send the percentage as a | ||
// number from 0 to 100, so we are going to multiply it by 100 | ||
final double cpuUsagePercentage = cpuNanosDiff / (double) realTimeNanosDiff; | ||
|
||
CpuCollectionData cpuData = | ||
new CpuCollectionData( | ||
System.currentTimeMillis(), (cpuUsagePercentage / (double) numCores) * 100.0); | ||
|
||
for (PerformanceCollectionData data : performanceCollectionData) { | ||
data.addCpuData(cpuData); | ||
} | ||
} | ||
|
||
/** Read the /proc/self/stat file and parses the result. */ | ||
private long readTotalCpuNanos() { | ||
String stat = null; | ||
try { | ||
stat = FileUtils.readText(selfStat); | ||
} catch (IOException e) { | ||
// If an error occurs when reading the file, we avoid reading it again until the setup method | ||
// is called again | ||
isEnabled = false; | ||
logger.log( | ||
SentryLevel.WARNING, "Unable to read /proc/self/stat file. Disabling cpu collection.", e); | ||
} | ||
if (stat != null) { | ||
stat = stat.trim(); | ||
String[] stats = stat.split("[\n\t\r ]"); | ||
try { | ||
// Amount of clock ticks this process has been scheduled in user mode | ||
long uTime = Long.parseLong(stats[13]); | ||
// Amount of clock ticks this process has been scheduled in kernel mode | ||
long sTime = Long.parseLong(stats[14]); | ||
// Amount of clock ticks this process' waited-for children has been scheduled in user mode | ||
long cuTime = Long.parseLong(stats[15]); | ||
// Amount of clock ticks this process' waited-for children has been scheduled in kernel mode | ||
long csTime = Long.parseLong(stats[16]); | ||
return (long) ((uTime + sTime + cuTime + csTime) * nanosecondsPerClockTick); | ||
} catch (NumberFormatException e) { | ||
logger.log(SentryLevel.ERROR, "Error parsing /proc/self/stat file.", e); | ||
return 0; | ||
} | ||
} | ||
return 0; | ||
} | ||
} |
17 changes: 13 additions & 4 deletions
17
sentry-android-core/src/main/java/io/sentry/android/core/AndroidMemoryCollector.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 |
---|---|---|
@@ -1,17 +1,26 @@ | ||
package io.sentry.android.core; | ||
|
||
import android.os.Debug; | ||
import io.sentry.IMemoryCollector; | ||
import io.sentry.ICollector; | ||
import io.sentry.MemoryCollectionData; | ||
import io.sentry.PerformanceCollectionData; | ||
import org.jetbrains.annotations.ApiStatus; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
@ApiStatus.Internal | ||
public class AndroidMemoryCollector implements IMemoryCollector { | ||
public class AndroidMemoryCollector implements ICollector { | ||
|
||
@Override | ||
public void setup() {} | ||
|
||
@Override | ||
public MemoryCollectionData collect() { | ||
public void collect(@NotNull Iterable<PerformanceCollectionData> performanceCollectionData) { | ||
long now = System.currentTimeMillis(); | ||
long usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); | ||
long usedNativeMemory = Debug.getNativeHeapSize() - Debug.getNativeHeapFreeSize(); | ||
return new MemoryCollectionData(now, usedMemory, usedNativeMemory); | ||
MemoryCollectionData memoryData = new MemoryCollectionData(now, usedMemory, usedNativeMemory); | ||
for (PerformanceCollectionData data : performanceCollectionData) { | ||
data.addMemoryData(memoryData); | ||
} | ||
} | ||
} |
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
Oops, something went wrong.