diff --git a/src/Sentry.Android.AssemblyReader/AndroidAssemblyReaderFactory.cs b/src/Sentry.Android.AssemblyReader/AndroidAssemblyReaderFactory.cs
index 62670899a9..e111a46f71 100644
--- a/src/Sentry.Android.AssemblyReader/AndroidAssemblyReaderFactory.cs
+++ b/src/Sentry.Android.AssemblyReader/AndroidAssemblyReaderFactory.cs
@@ -17,29 +17,29 @@ public static class AndroidAssemblyReaderFactory
/// The reader
public static IAndroidAssemblyReader Open(string apkPath, IList supportedAbis, DebugLogger? logger = null)
{
- logger?.Invoke("Opening APK: {0}", apkPath);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Opening APK: {0}", apkPath);
#if NET9_0
- logger?.Invoke("Reading files using V2 APK layout.");
+ logger?.Invoke(DebugLoggerLevel.Debug, "Reading files using V2 APK layout.");
if (AndroidAssemblyStoreReaderV2.TryReadStore(apkPath, supportedAbis, logger, out var readerV2))
{
- logger?.Invoke("APK uses AssemblyStore V2");
+ logger?.Invoke(DebugLoggerLevel.Debug, "APK uses AssemblyStore V2");
return readerV2;
}
- logger?.Invoke("APK doesn't use AssemblyStore");
+ logger?.Invoke(DebugLoggerLevel.Debug, "APK doesn't use AssemblyStore");
return new AndroidAssemblyDirectoryReaderV2(apkPath, supportedAbis, logger);
#else
- logger?.Invoke("Reading files using V1 APK layout.");
+ logger?.Invoke(DebugLoggerLevel.Debug, "Reading files using V1 APK layout.");
var zipArchive = ZipFile.OpenRead(apkPath);
if (zipArchive.GetEntry("assemblies/assemblies.manifest") is not null)
{
- logger?.Invoke("APK uses AssemblyStore V1");
+ logger?.Invoke(DebugLoggerLevel.Debug, "APK uses AssemblyStore V1");
return new AndroidAssemblyStoreReaderV1(zipArchive, supportedAbis, logger);
}
- logger?.Invoke("APK doesn't use AssemblyStore");
+ logger?.Invoke(DebugLoggerLevel.Debug, "APK doesn't use AssemblyStore");
return new AndroidAssemblyDirectoryReaderV1(zipArchive, supportedAbis, logger);
#endif
}
diff --git a/src/Sentry.Android.AssemblyReader/ArchiveUtils.cs b/src/Sentry.Android.AssemblyReader/ArchiveUtils.cs
index 0613eed1f9..d3b2f53e46 100644
--- a/src/Sentry.Android.AssemblyReader/ArchiveUtils.cs
+++ b/src/Sentry.Android.AssemblyReader/ArchiveUtils.cs
@@ -43,7 +43,7 @@ internal static MemoryStream Extract(this ZipArchiveEntry zipEntry)
Debug.Assert(inputStream.Position == payloadOffset);
var inputLength = (int)(inputStream.Length - payloadOffset);
- logger?.Invoke("Decompressing assembly ({0} bytes uncompressed) using LZ4", decompressedLength);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Decompressing assembly ({0} bytes uncompressed) using LZ4", decompressedLength);
var outputStream = new MemoryStream(decompressedLength);
diff --git a/src/Sentry.Android.AssemblyReader/DebugLogger.cs b/src/Sentry.Android.AssemblyReader/DebugLogger.cs
index aff0db80ca..d1835c55fa 100644
--- a/src/Sentry.Android.AssemblyReader/DebugLogger.cs
+++ b/src/Sentry.Android.AssemblyReader/DebugLogger.cs
@@ -3,6 +3,7 @@ namespace Sentry.Android.AssemblyReader;
///
/// Writes a log message for debugging.
///
+/// The debug log level.
/// The message string to write.
/// Arguments for the formatted message string.
-public delegate void DebugLogger(string message, params object?[] args);
+public delegate void DebugLogger(DebugLoggerLevel level, string message, params object?[] args);
diff --git a/src/Sentry.Android.AssemblyReader/DebugLoggerLevel.cs b/src/Sentry.Android.AssemblyReader/DebugLoggerLevel.cs
new file mode 100644
index 0000000000..886bafdc57
--- /dev/null
+++ b/src/Sentry.Android.AssemblyReader/DebugLoggerLevel.cs
@@ -0,0 +1,32 @@
+namespace Sentry.Android.AssemblyReader;
+
+///
+/// Represents the level of debug logging.
+///
+public enum DebugLoggerLevel : short
+{
+ ///
+ /// Debug level logging.
+ ///
+ Debug,
+
+ ///
+ /// Information level logging.
+ ///
+ Info,
+
+ ///
+ /// Warning level logging.
+ ///
+ Warning,
+
+ ///
+ /// Error level logging.
+ ///
+ Error,
+
+ ///
+ /// Fatal level logging.
+ ///
+ Fatal
+}
diff --git a/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyDirectoryReaderV1.cs b/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyDirectoryReaderV1.cs
index 30314a5546..7b5e1c1a7e 100644
--- a/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyDirectoryReaderV1.cs
+++ b/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyDirectoryReaderV1.cs
@@ -18,11 +18,11 @@ public AndroidAssemblyDirectoryReaderV1(ZipArchive zip, IList supportedA
var zipEntry = FindAssembly(name);
if (zipEntry is null)
{
- Logger?.Invoke("Couldn't find assembly {0} in the APK", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't find assembly {0} in the APK", name);
return null;
}
- Logger?.Invoke("Resolved assembly {0} in the APK at {1}", name, zipEntry.FullName);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Resolved assembly {0} in the APK at {1}", name, zipEntry.FullName);
// We need a seekable stream for the PEReader (or even to check whether the DLL is compressed), so make a copy.
var memStream = zipEntry.Extract();
diff --git a/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyStoreReaderV1.cs b/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyStoreReaderV1.cs
index 3073cc2095..60c947b23e 100644
--- a/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyStoreReaderV1.cs
+++ b/src/Sentry.Android.AssemblyReader/V1/AndroidAssemblyStoreReaderV1.cs
@@ -16,16 +16,16 @@ public AndroidAssemblyStoreReaderV1(ZipArchive zip, IList supportedAbis,
var assembly = TryFindAssembly(name);
if (assembly is null)
{
- Logger?.Invoke("Couldn't find assembly {0} in the APK AssemblyStore", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't find assembly {0} in the APK AssemblyStore", name);
return null;
}
- Logger?.Invoke("Resolved assembly {0} in the APK {1} AssemblyStore", name, assembly.Store.Arch);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Resolved assembly {0} in the APK {1} AssemblyStore", name, assembly.Store.Arch);
var stream = assembly.GetImage();
if (stream is null)
{
- Logger?.Invoke("Couldn't access assembly {0} image stream", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't access assembly {0} image stream", name);
return null;
}
@@ -119,7 +119,7 @@ private void ProcessStores()
assembly.Hash64 = he.Hash;
if (assembly.RuntimeIndex != he.MappingIndex)
{
- _logger?.Invoke(
+ _logger?.Invoke(DebugLoggerLevel.Debug,
$"assembly with hashes 0x{assembly.Hash32} and 0x{assembly.Hash64} has a different 32-bit runtime index ({assembly.RuntimeIndex}) than the 64-bit runtime index({he.MappingIndex})");
}
@@ -127,18 +127,18 @@ private void ProcessStores()
{
if (string.IsNullOrEmpty(assembly.Name))
{
- _logger?.Invoke(
+ _logger?.Invoke(DebugLoggerLevel.Debug,
$"32-bit hash 0x{assembly.Hash32:x} did not match any assembly name in the manifest");
assembly.Name = me.Name;
if (string.IsNullOrEmpty(assembly.Name))
{
- _logger?.Invoke(
+ _logger?.Invoke(DebugLoggerLevel.Debug,
$"64-bit hash 0x{assembly.Hash64:x} did not match any assembly name in the manifest");
}
}
else if (!string.Equals(assembly.Name, me.Name, StringComparison.Ordinal))
{
- _logger?.Invoke(
+ _logger?.Invoke(DebugLoggerLevel.Debug,
$"32-bit hash 0x{assembly.Hash32:x} maps to assembly name '{assembly.Name}', however 64-bit hash 0x{assembly.Hash64:x} for the same entry matches assembly name '{me.Name}'");
}
}
@@ -176,7 +176,7 @@ void ProcessIndex(List index, string bitness,
{
if (!Stores.TryGetValue(he.StoreId, out var storeList))
{
- _logger?.Invoke($"store with id {he.StoreId} not part of the set");
+ _logger?.Invoke(DebugLoggerLevel.Debug, $"store with id {he.StoreId} not part of the set");
continue;
}
@@ -184,7 +184,7 @@ void ProcessIndex(List index, string bitness,
{
if (he.LocalStoreIndex >= (uint)store.Assemblies.Count)
{
- _logger?.Invoke(
+ _logger?.Invoke(DebugLoggerLevel.Debug,
$"{bitness}-bit index entry with hash 0x{he.Hash:x} has invalid store {store.StoreId} index {he.LocalStoreIndex} (maximum allowed is {store.Assemblies.Count})");
continue;
}
diff --git a/src/Sentry.Android.AssemblyReader/V2/AndroidAssemblyDirectoryReaderV2.cs b/src/Sentry.Android.AssemblyReader/V2/AndroidAssemblyDirectoryReaderV2.cs
index 7c92c70a26..b250640d1f 100644
--- a/src/Sentry.Android.AssemblyReader/V2/AndroidAssemblyDirectoryReaderV2.cs
+++ b/src/Sentry.Android.AssemblyReader/V2/AndroidAssemblyDirectoryReaderV2.cs
@@ -12,7 +12,7 @@ public AndroidAssemblyDirectoryReaderV2(string apkPath, IList supportedA
Logger = logger;
foreach (var abi in supportedAbis)
{
- logger?.Invoke("Adding {0} to supported architectures for Directory Reader", abi);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Adding {0} to supported architectures for Directory Reader", abi);
SupportedArchitectures.Add(abi.AbiToDeviceArchitecture());
}
_archiveAssemblyHelper = new ArchiveAssemblyHelper(apkPath, logger, supportedAbis);
@@ -26,21 +26,21 @@ public AndroidAssemblyDirectoryReaderV2(string apkPath, IList supportedA
var stream = File.OpenRead(name);
return new PEReader(stream);
}
- Logger?.Invoke("File {0} does not exist in the APK", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "File {0} does not exist in the APK", name);
foreach (var arch in SupportedArchitectures)
{
if (_archiveAssemblyHelper.ReadEntry($"assemblies/{name}", arch) is not { } memStream)
{
- Logger?.Invoke("Couldn't find entry {0} in the APK for the {1} architecture", name, arch);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't find entry {0} in the APK for the {1} architecture", name, arch);
continue;
}
- Logger?.Invoke("Resolved assembly {0} in the APK", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Resolved assembly {0} in the APK", name);
return ArchiveUtils.CreatePEReader(name, memStream, Logger);
}
- Logger?.Invoke("Couldn't find assembly {0} in the APK", name);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't find assembly {0} in the APK", name);
return null;
}
@@ -96,11 +96,11 @@ public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger, IList $"Entry '{path}' does not contain the 'payload' section",
_ => $"Unknown ELF payload section error for entry '{path}': {error}"
};
- _logger?.Invoke(message);
+ _logger?.Invoke(DebugLoggerLevel.Debug, message);
}
else
{
- _logger?.Invoke($"Extracted content from ELF image '{path}'");
+ _logger?.Invoke(DebugLoggerLevel.Debug, $"Extracted content from ELF image '{path}'");
}
if (elfPayloadOffset == 0)
@@ -142,14 +142,14 @@ public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger, IList supportedAbis, D
var (explorers, errorMessage) = AssemblyStoreExplorer.Open(inputFile, logger);
if (explorers is null)
{
- logger?.Invoke("Unable to read store information for {0}: {1}", inputFile, errorMessage);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Unable to read store information for {0}: {1}", inputFile, errorMessage);
// Check for assembly stores in any device specific APKs
foreach (var supportedAbi in supportedAbis)
@@ -27,7 +27,7 @@ public static bool TryReadStore(string inputFile, IList supportedAbis, D
var splitFilePath = inputFile.GetArchivePathForAbi(supportedAbi, logger);
if (!File.Exists(splitFilePath))
{
- logger?.Invoke("No split config detected at: '{0}'", splitFilePath);
+ logger?.Invoke(DebugLoggerLevel.Debug, "No split config detected at: '{0}'", splitFilePath);
continue;
}
(explorers, errorMessage) = AssemblyStoreExplorer.Open(splitFilePath, logger);
@@ -37,7 +37,7 @@ public static bool TryReadStore(string inputFile, IList supportedAbis, D
}
else
{
- logger?.Invoke("Unable to read store information for {0}: {1}", splitFilePath, errorMessage);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Unable to read store information for {0}: {1}", splitFilePath, errorMessage);
}
}
}
@@ -62,7 +62,7 @@ public static bool TryReadStore(string inputFile, IList supportedAbis, D
if (supportedExplorers.Count == 0)
{
- logger?.Invoke("Could not find V2 AssemblyStoreExplorer for the supported ABIs: {0}", string.Join(", ", supportedAbis));
+ logger?.Invoke(DebugLoggerLevel.Debug, "Could not find V2 AssemblyStoreExplorer for the supported ABIs: {0}", string.Join(", ", supportedAbis));
reader = null;
return false;
}
@@ -76,17 +76,17 @@ public static bool TryReadStore(string inputFile, IList supportedAbis, D
var explorerAssembly = TryFindAssembly(name);
if (explorerAssembly is null)
{
- _logger?.Invoke("Couldn't find assembly {0} in the APK AssemblyStore", name);
+ _logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't find assembly {0} in the APK AssemblyStore", name);
return null;
}
var (explorer, storeItem) = explorerAssembly;
- _logger?.Invoke("Resolved assembly {0} in the APK {1} AssemblyStore", name, storeItem.TargetArch);
+ _logger?.Invoke(DebugLoggerLevel.Debug, "Resolved assembly {0} in the APK {1} AssemblyStore", name, storeItem.TargetArch);
var stream = explorer.ReadImageData(storeItem, false);
if (stream is null)
{
- _logger?.Invoke("Couldn't access assembly {0} image stream", name);
+ _logger?.Invoke(DebugLoggerLevel.Debug, "Couldn't access assembly {0} image stream", name);
return null;
}
@@ -127,12 +127,12 @@ private bool FindBestAssembly(string name, out ExplorerStoreItem? explorerAssemb
{
if (explorer.AssembliesByName?.TryGetValue(name, out var assembly) is true)
{
- _logger?.Invoke("Found best assembly {0} in APK AssemblyStore for target arch {1}", name, explorer.TargetArch);
+ _logger?.Invoke(DebugLoggerLevel.Debug, "Found best assembly {0} in APK AssemblyStore for target arch {1}", name, explorer.TargetArch);
explorerAssembly = new(explorer, assembly);
return true;
}
}
- _logger?.Invoke("No best assembly for {0} in APK AssemblyStore", name);
+ _logger?.Invoke(DebugLoggerLevel.Warning, "No best assembly for {0} in APK AssemblyStore", name);
explorerAssembly = null;
return false;
}
diff --git a/src/Sentry.Android.AssemblyReader/V2/AssemblyStoreExplorer.cs b/src/Sentry.Android.AssemblyReader/V2/AssemblyStoreExplorer.cs
index 424109bcee..0ab9c04e2e 100644
--- a/src/Sentry.Android.AssemblyReader/V2/AssemblyStoreExplorer.cs
+++ b/src/Sentry.Android.AssemblyReader/V2/AssemblyStoreExplorer.cs
@@ -33,7 +33,7 @@ private AssemblyStoreExplorer(Stream storeStream, string path, DebugLogger? logg
{
foreach (var item in Assemblies)
{
- logger?.Invoke("Assembly {0} indexed from AssemblyStore {1}", item.Name, path);
+ logger?.Invoke(DebugLoggerLevel.Debug, "Assembly {0} indexed from AssemblyStore {1}", item.Name, path);
dict.Add(item.Name, item);
}
}
diff --git a/src/Sentry.Android.AssemblyReader/V2/StoreReaderV2.cs b/src/Sentry.Android.AssemblyReader/V2/StoreReaderV2.cs
index 6a40e05bc0..97bac95694 100644
--- a/src/Sentry.Android.AssemblyReader/V2/StoreReaderV2.cs
+++ b/src/Sentry.Android.AssemblyReader/V2/StoreReaderV2.cs
@@ -106,7 +106,7 @@ protected override bool IsSupported()
ELFPayloadError.NoPayloadSection => $"Store '{StorePath}' does not contain the 'payload' section",
_ => $"Unknown ELF payload section error for store '{StorePath}': {error}"
};
- Logger?.Invoke(message);
+ Logger?.Invoke(DebugLoggerLevel.Debug, message);
// Was originally:
// ```
// } else if (elfOffset >= 0) {
@@ -122,14 +122,14 @@ protected override bool IsSupported()
if (magic != Utils.AssemblyStoreMagic)
{
- Logger?.Invoke("Store '{0}' has invalid header magic number.", StorePath);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Store '{0}' has invalid header magic number.", StorePath);
return false;
}
uint version = reader.ReadUInt32();
if (!supportedVersions.Contains(version))
{
- Logger?.Invoke("Store '{0}' has unsupported version 0x{1:x}", StorePath, version);
+ Logger?.Invoke(DebugLoggerLevel.Debug, "Store '{0}' has unsupported version 0x{1:x}", StorePath, version);
return false;
}
diff --git a/src/Sentry/Platforms/Android/AndroidHelpers.cs b/src/Sentry/Platforms/Android/AndroidHelpers.cs
index c33d404e08..41fa2c8b1f 100644
--- a/src/Sentry/Platforms/Android/AndroidHelpers.cs
+++ b/src/Sentry/Platforms/Android/AndroidHelpers.cs
@@ -44,7 +44,7 @@ public static IList GetSupportedAbis()
{
var supportedAbis = GetSupportedAbis();
return AndroidAssemblyReaderFactory.Open(apkPath, supportedAbis,
- logger: (message, args) => logger?.Log(SentryLevel.Debug, message, args: args));
+ logger: (level, message, args) => logger?.Log((SentryLevel)level, message, args: args));
}
catch (Exception ex)
{
diff --git a/test/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.cs b/test/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.cs
index 4a9985f827..24344f2edd 100644
--- a/test/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.cs
+++ b/test/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.cs
@@ -39,7 +39,7 @@ private IAndroidAssemblyReader GetSut(bool isAot, bool isAssemblyStore, bool isC
// Note: This needs to match the RID used when publishing the test APK
string[] supportedAbis = { "x86_64" };
return AndroidAssemblyReaderFactory.Open(apkPath, supportedAbis,
- logger: (message, args) => _output.WriteLine(message, args));
+ logger: (_, message, args) => _output.WriteLine(message, args));
#endif
}
diff --git a/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
index 42c0fac236..67bbca78b3 100644
--- a/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
+++ b/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
@@ -4,7 +4,15 @@
{
public static Sentry.Android.AssemblyReader.IAndroidAssemblyReader Open(string apkPath, System.Collections.Generic.IList supportedAbis, Sentry.Android.AssemblyReader.DebugLogger? logger = null) { }
}
- public delegate void DebugLogger(string message, params object?[] args);
+ public delegate void DebugLogger(Sentry.Android.AssemblyReader.DebugLoggerLevel level, string message, params object?[] args);
+ public enum DebugLoggerLevel : short
+ {
+ Debug = 0,
+ Info = 1,
+ Warning = 2,
+ Error = 3,
+ Fatal = 4,
+ }
public interface IAndroidAssemblyReader : System.IDisposable
{
System.Reflection.PortableExecutable.PEReader? TryReadAssembly(string name);
diff --git a/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt b/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
index 42c0fac236..67bbca78b3 100644
--- a/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
+++ b/test/Sentry.Android.AssemblyReader.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
@@ -4,7 +4,15 @@
{
public static Sentry.Android.AssemblyReader.IAndroidAssemblyReader Open(string apkPath, System.Collections.Generic.IList supportedAbis, Sentry.Android.AssemblyReader.DebugLogger? logger = null) { }
}
- public delegate void DebugLogger(string message, params object?[] args);
+ public delegate void DebugLogger(Sentry.Android.AssemblyReader.DebugLoggerLevel level, string message, params object?[] args);
+ public enum DebugLoggerLevel : short
+ {
+ Debug = 0,
+ Info = 1,
+ Warning = 2,
+ Error = 3,
+ Fatal = 4,
+ }
public interface IAndroidAssemblyReader : System.IDisposable
{
System.Reflection.PortableExecutable.PEReader? TryReadAssembly(string name);