From b7ecb4d54f4099032707041f22518f6fb20ec74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 11:48:59 +0100 Subject: [PATCH 01/56] Update to Core 14.0.1 --- CHANGELOG.md | 6 ++++-- .../kotlin/internal/interop/RealmInterop.kt | 18 +++++++++++++++--- .../kotlin/internal/interop/RealmInterop.kt | 12 +++++++++--- packages/external/core | 2 +- packages/jni-swig-stub/realm.i | 4 +++- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90ff0279e1..c7d6071fd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ ## 1.14.0 (2024-03-08) +This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from fileformat v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. + ### Breaking Changes * None. @@ -68,9 +70,9 @@ ### Internal * Update to Ktor 2.3.4. * Updated to CMake 3.27.7 -* Updated to Realm Core 13.26.0, commit 5533505d18fda93a7a971d58a191db5005583c92. +* Updated to Realm Core 14.0.1 commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730. * Adding Sync tests via Github Action. -* Updated to Swig 4.2.0. (Issue [GitHub #1632](https://github.com/realm/realm-kotlin/issues/1632)[JIRA RKOTLIN-1001](https://jira.mongodb.org/browse/RKOTLIN-1001)) +* Updated to Swig 4.2.0. (Issue [GitHub #1632](https://github.com/realm/realm-kotlin/issues/1632) [JIRA RKOTLIN-1001](https://jira.mongodb.org/browse/RKOTLIN-1001)) ## 1.13.1-SNAPSHOT (YYYY-MM-DD) diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index b79c41f4f4..58254b507c 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -942,7 +942,11 @@ actual object RealmInterop { val deletionCount = LongArray(1) val modificationCount = LongArray(1) val movesCount = LongArray(1) + // Not exposed in SDK yet, but could be used to provide optimized notifications when + // collections are cleared. + // https://github.com/realm/realm-kotlin/issues/1498 val collectionWasCleared = BooleanArray(1) + val collectionWasDeleted = BooleanArray(1) realmc.realm_collection_changes_get_num_changes( change.cptr(), @@ -950,7 +954,8 @@ actual object RealmInterop { insertionCount, modificationCount, movesCount, - collectionWasCleared + collectionWasCleared, + collectionWasDeleted, ) val insertionIndices: LongArray = initIndicesArray(insertionCount) @@ -1042,16 +1047,22 @@ actual object RealmInterop { val deletions = longArrayOf(0) val insertions = longArrayOf(0) val modifications = longArrayOf(0) + val collectionWasDeleted = BooleanArray(1) realmc.realm_dictionary_get_changes( change.cptr(), deletions, insertions, - modifications + modifications, + collectionWasDeleted ) val deletionStructs = realmc.new_valueArray(deletions[0].toInt()) val insertionStructs = realmc.new_valueArray(insertions[0].toInt()) val modificationStructs = realmc.new_valueArray(modifications[0].toInt()) + // Not exposed in SDK yet, but could be used to provide optimized notifications when + // collections are cleared. + // https://github.com/realm/realm-kotlin/issues/1498 + val collectionWasCleared = booleanArrayOf(false) realmc.realm_dictionary_get_changed_keys( change.cptr(), deletionStructs, @@ -1059,7 +1070,8 @@ actual object RealmInterop { insertionStructs, insertions, modificationStructs, - modifications + modifications, + collectionWasCleared, ) // TODO optimize - integrate within mem allocator? diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 3b0faf5100..640bd75b4e 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -1864,6 +1864,7 @@ actual object RealmInterop { val modificationCount = allocArray(1) val movesCount = allocArray(1) val collectionWasErased = alloc() + val collectionWasDeleted = alloc() realm_wrapper.realm_collection_changes_get_num_changes( change.cptr(), @@ -1871,7 +1872,8 @@ actual object RealmInterop { insertionCount, modificationCount, movesCount, - collectionWasErased.ptr + collectionWasErased.ptr, + collectionWasDeleted.ptr, ) val deletionIndices = initArray(deletionCount) @@ -1953,12 +1955,15 @@ actual object RealmInterop { val deletions = allocArray(1) val insertions = allocArray(1) val modifications = allocArray(1) + val collectionWasCleared = alloc() + val collectionWasDeleted = alloc() realm_wrapper.realm_dictionary_get_changes( change.cptr(), deletions, insertions, - modifications + modifications, + collectionWasDeleted.ptr ) val deletionStructs = allocArray(deletions[0].toInt()) val insertionStructs = allocArray(insertions[0].toInt()) @@ -1971,7 +1976,8 @@ actual object RealmInterop { insertionStructs, insertions, modificationStructs, - modifications + modifications, + collectionWasCleared.ptr ) val deletedKeys = (0 until deletions[0].toInt()).map { diff --git a/packages/external/core b/packages/external/core index 5533505d18..b1d32d3d20 160000 --- a/packages/external/core +++ b/packages/external/core @@ -1 +1 @@ -Subproject commit 5533505d18fda93a7a971d58a191db5005583c92 +Subproject commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730 diff --git a/packages/jni-swig-stub/realm.i b/packages/jni-swig-stub/realm.i index bbbad4dcbd..9ea8b25428 100644 --- a/packages/jni-swig-stub/realm.i +++ b/packages/jni-swig-stub/realm.i @@ -365,7 +365,9 @@ import static io.realm.kotlin.internal.interop.realm_errno_e.*; // bool output parameter %apply bool* OUTPUT { bool* out_found, bool* did_create, bool* did_delete_realm, bool* out_inserted, bool* erased, bool* out_erased, bool* did_refresh, bool* did_run, - bool* found, bool* out_collection_was_cleared, bool* did_compact }; + bool* found, bool* out_collection_was_cleared, bool* did_compact, + bool* collection_was_cleared, bool* out_collection_was_deleted, + bool* out_was_deleted}; // uint64_t output parameter for realm_get_num_versions %apply int64_t* OUTPUT { uint64_t* out_versions_count }; From 5b83ad2bcfe63f2c3a72d8e4cea631da3287d8e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 14:42:47 +0100 Subject: [PATCH 02/56] Dump cmake version on GHA build --- .github/workflows/pr.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f0a427b33a..73c1e606ff 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -61,8 +61,11 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: - cmake-version: ${{ vars.VERSION_CMAKE }} - + cmake-version: '${{ vars.VERSION_CMAKE }}' + + - name: Use cmake + run: cmake --version + # Manually install SWIG 4.1.1 as only 4.0.2 is pre-installed # 4.1.1 is not available in apt-get, so use brew instead # We need to use the formulae directly from GitHub to pin the version as Homebrew does not have From 06c75b8e60a8223756c80215337a4e0712130863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 14:50:38 +0100 Subject: [PATCH 03/56] Additional GHA debug info --- .github/workflows/pr.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 73c1e606ff..c3833b003e 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -122,6 +122,9 @@ jobs: with: cmake-version: ${{ vars.VERSION_CMAKE }} + - name: Use cmake + run: cmake --version + - name: Restore JNI Swig Stubs uses: actions/download-artifact@v3 with: @@ -546,7 +549,10 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: - cmake-version: ${{ vars.VERSION_CMAKE }} + cmake-version: '${{ vars.VERSION_CMAKE }}' + + - name: Use cmake + run: cmake --version - name: Setup ninja uses: cmelchior/setup-ninja@master From 2f02b5b3c678e72e95140a74b78e27c5b00af8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 15:07:16 +0100 Subject: [PATCH 04/56] Update CMAKE on JVM linux docker image --- packages/cinterop/src/jvmMain/generic.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cinterop/src/jvmMain/generic.Dockerfile b/packages/cinterop/src/jvmMain/generic.Dockerfile index 627f1c144f..26da693918 100644 --- a/packages/cinterop/src/jvmMain/generic.Dockerfile +++ b/packages/cinterop/src/jvmMain/generic.Dockerfile @@ -21,7 +21,7 @@ ENV PATH /opt/cmake/bin:/opt/rh/rh-git218/root/usr/bin:/opt/rh/devtoolset-9/root ENV LD_LIBRARY_PATH /opt/rh/devtoolset-9/root/usr/lib64:/opt/rh/devtoolset-9/root/usr/lib:/opt/rh/devtoolset-9/root/usr/lib64/dyninst:/opt/rh/devtoolset-9/root/usr/lib/dyninst:/opt/rh/devtoolset-9/root/usr/lib64:/opt/rh/devtoolset-9/root/usr/lib RUN mkdir -p /opt/cmake \ - && curl https://cmake.org/files/v3.18/cmake-3.18.2-Linux-x86_64.sh -o /cmake.sh \ + && curl https://cmake.org/files/v3.27/cmake-3.27.7-linux-x86_64.sh -o /cmake.sh \ && sh /cmake.sh --prefix=/opt/cmake --skip-license \ && rm /cmake.sh From 8fdd84eafa009d996fb6d77d431e6e0f211f4c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 16:15:57 +0100 Subject: [PATCH 05/56] Bump NDK to fix core link issues --- buildSrc/src/main/kotlin/Config.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index b6631f5b29..1b143e9e31 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -102,7 +102,7 @@ object Versions { const val compileSdkVersion = 33 const val buildToolsVersion = "33.0.0" const val buildTools = "7.3.1" // https://maven.google.com/web/index.html?q=gradle#com.android.tools.build:gradle - const val ndkVersion = "23.2.8568313" + const val ndkVersion = "24.0.8215888" const val r8 = "8.0.34" // See https://developer.android.com/build/kotlin-support } const val androidxBenchmarkPlugin = "1.2.0-alpha12" // https://maven.google.com/web/index.html#androidx.benchmark:androidx.benchmark.gradle.plugin From b8232d3dd5b1add6226778e668cfc60a942689ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 28 Feb 2024 17:03:53 +0100 Subject: [PATCH 06/56] Bump NDK to fix core link issues --- buildSrc/src/main/kotlin/Config.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index 1b143e9e31..f4be34cf78 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -102,7 +102,7 @@ object Versions { const val compileSdkVersion = 33 const val buildToolsVersion = "33.0.0" const val buildTools = "7.3.1" // https://maven.google.com/web/index.html?q=gradle#com.android.tools.build:gradle - const val ndkVersion = "24.0.8215888" + const val ndkVersion = "26.2.11394342" const val r8 = "8.0.34" // See https://developer.android.com/build/kotlin-support } const val androidxBenchmarkPlugin = "1.2.0-alpha12" // https://maven.google.com/web/index.html#androidx.benchmark:androidx.benchmark.gradle.plugin From f6364d2f10205fff429616c61dd4fb591668cdb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Thu, 29 Feb 2024 09:44:19 +0100 Subject: [PATCH 07/56] Fix expected exception text in query test --- .../commonTest/kotlin/io/realm/kotlin/test/common/QueryTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/QueryTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/QueryTests.kt index 1292ea5079..0b6eb5dc3c 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/QueryTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/QueryTests.kt @@ -114,7 +114,7 @@ class QueryTests { @Test fun query_wrongArgumentTypeThrows() { - assertFailsWithMessage(" Unsupported comparison between type 'string' and type 'bool'") { + assertFailsWithMessage("Cannot compare argument \$0 with value 'true' to a string") { realm.query("stringField = $0", true) } } From 7f2257c7a36b68d8c6fd4ea4ba16353ae883c6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Thu, 29 Feb 2024 10:27:53 +0100 Subject: [PATCH 08/56] Clean up debug output --- .github/workflows/pr.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c3833b003e..75830a3dce 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -61,10 +61,7 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: - cmake-version: '${{ vars.VERSION_CMAKE }}' - - - name: Use cmake - run: cmake --version + cmake-version: ${{ vars.VERSION_CMAKE }} # Manually install SWIG 4.1.1 as only 4.0.2 is pre-installed # 4.1.1 is not available in apt-get, so use brew instead @@ -122,9 +119,6 @@ jobs: with: cmake-version: ${{ vars.VERSION_CMAKE }} - - name: Use cmake - run: cmake --version - - name: Restore JNI Swig Stubs uses: actions/download-artifact@v3 with: @@ -551,9 +545,6 @@ jobs: with: cmake-version: '${{ vars.VERSION_CMAKE }}' - - name: Use cmake - run: cmake --version - - name: Setup ninja uses: cmelchior/setup-ninja@master with: From d74df611f65ee4857609233b60e7eaaf5f44d060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Thu, 29 Feb 2024 10:35:21 +0100 Subject: [PATCH 09/56] More clean up --- .github/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 75830a3dce..29363a34ba 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -543,7 +543,7 @@ jobs: - name: Setup cmake uses: jwlawson/actions-setup-cmake@v1.13 with: - cmake-version: '${{ vars.VERSION_CMAKE }}' + cmake-version: ${{ vars.VERSION_CMAKE }} - name: Setup ninja uses: cmelchior/setup-ninja@master From 7a9933b38088aecb0b026b7f0d603b8a546a9b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Mon, 4 Mar 2024 11:16:54 +0100 Subject: [PATCH 10/56] Revert NDK to debug arm7v issues --- .github/workflows/pr.yml | 2 +- buildSrc/src/main/kotlin/Config.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 29363a34ba..fb8e8ba4ef 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -583,7 +583,7 @@ jobs: - name: Build packages working-directory: packages - run: ./gradlew publishCIPackages -Prealm.kotlin.targets=android -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false + run: ./gradlew publishCIPackages -Prealm.kotlin.targets=android -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info - name: Store build cache uses: actions/cache@v3 diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index f4be34cf78..b6631f5b29 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -102,7 +102,7 @@ object Versions { const val compileSdkVersion = 33 const val buildToolsVersion = "33.0.0" const val buildTools = "7.3.1" // https://maven.google.com/web/index.html?q=gradle#com.android.tools.build:gradle - const val ndkVersion = "26.2.11394342" + const val ndkVersion = "23.2.8568313" const val r8 = "8.0.34" // See https://developer.android.com/build/kotlin-support } const val androidxBenchmarkPlugin = "1.2.0-alpha12" // https://maven.google.com/web/index.html#androidx.benchmark:androidx.benchmark.gradle.plugin From 2afec66d7c5403f94a48ad9d6a8c720f9e81c9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Mon, 4 Mar 2024 11:24:19 +0100 Subject: [PATCH 11/56] More debug info --- .github/workflows/pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index fb8e8ba4ef..ccbbcfd08c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -575,11 +575,11 @@ jobs: - name: Build Android Base Test Apk working-directory: packages - run: ./gradlew :test-base:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false + run: ./gradlew :test-base:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info - name: Build Android Sync Test Apk working-directory: packages - run: ./gradlew :test-sync:packageDebug :test-sync:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false + run: ./gradlew :test-sync:packageDebug :test-sync:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info - name: Build packages working-directory: packages From 85781aaf595f0d304c8e26bea4a8168591c479ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 6 Mar 2024 15:00:28 +0100 Subject: [PATCH 12/56] Included core updates in CHANGELOG --- CHANGELOG.md | 135 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d6071fd5..61d3f45d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,36 +1,94 @@ ## 1.15.0-SNAPSHOT (YYYY-MM-DD) -### Breaking Changes +[!NOTE] +This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from fileformat v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. -- None. +### Breaking changes +### Core-14.0.0 +* If you want to query using @type operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types. +### Core-14.0.0-beta0 + + +* BinaryData and StringData are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a Mixed property, as now only strings will be returned. If searching for BinaryData is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. ([6407](https://github.com/realm/realm-core/issues/6407)). + +* Sorting order of strings has changed to use standard unicode codepoint order instead of grouping similar english letters together. A noticeable change will be from "aAbBzZ" to "ABZabz". ([2573](https://github.com/realm/realm-core/issues/2573)) ### Enhancements - -- None. +### Core-14.1.0 +* Add support for using aggregate operations on Mixed properties in queries ([PR #7398](https://github.com/realm/realm-core/pull/7398)) +### Core-14.0.0 +* Property keypath in RQL can be substituted with value given as argument. Use '$P' in query string. (Issue [#7033](https://github.com/realm/realm-core/issues/7033)) +* You can now use query substitution for the @type argument ([#7289](https://github.com/realm/realm-core/issues/7289)) +### Core-14.0.0-beta0 +* Storage of Decimal128 properties has been optimised so that the individual values will take up 0 bits (if all nulls), 32 bits, 64 bits or 128 bits depending on what is needed. (PR [#6111](https://github.com/realm/realm-core/pull/6111)) +* Querying a specific entry in a collection (in particular 'first and 'last') is supported. (PR [#4269](https://github.com/realm/realm-core/issues/4269)) +* Index on list of strings property now supported (PR [#7142](https://github.com/realm/realm-core/pull/7142)) +### 13.27.0 + + +* Improved performance of RQL (parsed) queries on a non-linked string property using: >, >=, <, <=, operators and fixed behaviour that a null string should be evaulated as less than everything, previously nulls were not matched. ([#3939](https://github.com/realm/realm-core/issues/3939), this is a prerequisite for https://github.com/realm/realm-swift/issues/8008). +* Updated bundled OpenSSL version to 3.2.0 (PR [#7303](https://github.com/realm/realm-core/pull/7303)) + + + + ### Fixed - -- None. +### Core-14.1.0 + + + + + + + + +### Core-14.0.0 + + + + + +* `@count`/`@size` is now supported for mixed properties ([#7280](https://github.com/realm/realm-core/issues/7280), since v10.0.0) + + + + +### Core-14.0.0-beta0 + +* Fixed equality queries on a Mixed property with an index possibly returning the wrong result if values of different types happened to have the same StringIndex hash. ([6407](https://github.com/realm/realm-core/issues/6407) since v11.0.0-beta.5). +* If you have more than 8388606 links pointing to one specific object, the program will crash. ([#6577](https://github.com/realm/realm-core/issues/6577), since v6.0.0) +* Query for NULL value in Dictionary would give wrong results ([6748])(https://github.com/realm/realm-core/issues/6748), since v10.0.0) + +### 13.27.0 +* Fixed queries like `indexed_property == NONE {x}` which mistakenly matched on only x instead of not x. This only applies when an indexed property with equality (==, or IN) matches with `NONE` on a list of one item. If the constant list contained more than one value then it was working correctly. ([realm-js #7862](https://github.com/realm/realm-java/issues/7862), since v12.5.0) +* Uploading the changesets recovered during an automatic client reset recovery may lead to 'Bad server version' errors and a new client reset. ([#7279](https://github.com/realm/realm-core/issues/7279), since v13.24.1) + +* Fixed crash in fulltext index using prefix search with no matches ([#7309](https://github.com/realm/realm-core/issues/7309), since v13.18.0) + + + + +* Fix a minor race condition when backing up Realm files before a client reset which could have lead to overwriting an existing file. ([PR #7341](https://github.com/realm/realm-core/pull/7341)). ### Compatibility - -- File format: Generates Realms with file format v23. -- Realm Studio 13.0.0 or above is required to open Realms created by this version. -- This release is compatible with the following Kotlin releases: - - Kotlin 1.9.0 and above. Support for experimental K2-compilation with `kotlin.experimental.tryK2=true`. - - Ktor 2.1.2 and above. - - Coroutines 1.7.0 and above. - - AtomicFu 0.18.3 and above. - - The new memory model only. See https://github.com/realm/realm-kotlin#kotlin-memory-model-and-coroutine-compatibility -- Minimum Kbson 0.3.0. -- Minimum Gradle version: 6.8.3. -- Minimum Android Gradle Plugin version: 4.1.3. -- Minimum Android SDK: 16. -- Minimum R8: 8.0.34. +* File format: Generates Realms with file format v24 (reads and upgrades file format v10 or later). +* Realm Studio 15.0.0 or above is required to open Realms created by this version. +* This release is compatible with the following Kotlin releases: + * Kotlin 1.9.0 and above. Support for experimental K2-compilation with `kotlin.experimental.tryK2=true`. + * Ktor 2.1.2 and above. + * Coroutines 1.7.0 and above. + * AtomicFu 0.18.3 and above. + * The new memory model only. See https://github.com/realm/realm-kotlin#kotlin-memory-model-and-coroutine-compatibility +* Minimum Kbson 0.3.0. +* Minimum Gradle version: 6.8.3. +* Minimum Android Gradle Plugin version: 4.1.3. +* Minimum Android SDK: 16. +* Minimum R8: 8.0.34. ### Internal +* Updated to Realm Core 14.1.0 commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730. -- None. ## 1.14.0 (2024-03-08) @@ -48,6 +106,8 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Cache notification callback JNI references at startup to ensure that symbols can be resolved in core callbacks. (Issue [#1577](https://github.com/realm/realm-kotlin/issues/1577)) * Using `Realm.asFlow()` could miss an update if a write was started right after opening the Realm. (Issue [#1582](https://github.com/realm/realm-kotlin/issues/1582)) * Guarded analytic errors so that they do not fail user builds. +* Using keypaths in Flows could sometimes throw `java.lang.IllegalStateException: [RLM_ERR_WRONG_THREAD]: Realm accessed from incorrect thread.`. (Issue [#1594](https://github.com/realm/realm-kotlin/pull/1594, since 1.13.0) +* Non-`IllegalStateExceptions` in a `write`-block would not cancel transactions, but leave it open. (Issue [#1615](https://github.com/realm/realm-kotlin/issues/1615)). * [Sync] `NullPointerException` while waiting for the synchronization of a subscription set if the client was set in `AwaitingMark` state. (Issue [#1671](https://github.com/realm/realm-kotlin/issues/1671) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1027)) * Github Action: Snapshot publishing with Github Action. (Issue [#1654](https://github.com/realm/realm-kotlin/issues/1654) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1018)) * Github Action: automate release process to Maven Central. (Issue [JIRA](https://jira.mongodb.org/browse/RKOTLIN-709)) @@ -70,42 +130,11 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi ### Internal * Update to Ktor 2.3.4. * Updated to CMake 3.27.7 -* Updated to Realm Core 14.0.1 commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730. +* Updated to Realm Core 13.26.0, commit 5533505d18fda93a7a971d58a191db5005583c92. * Adding Sync tests via Github Action. * Updated to Swig 4.2.0. (Issue [GitHub #1632](https://github.com/realm/realm-kotlin/issues/1632) [JIRA RKOTLIN-1001](https://jira.mongodb.org/browse/RKOTLIN-1001)) -## 1.13.1-SNAPSHOT (YYYY-MM-DD) - -### Breaking Changes -* None. - -### Enhancements -* None. - -### Fixed -* Using keypaths in Flows could sometimes throw `java.lang.IllegalStateException: [RLM_ERR_WRONG_THREAD]: Realm accessed from incorrect thread.`. (Issue [#1594](https://github.com/realm/realm-kotlin/pull/1594, since 1.13.0) -* Non-`IllegalStateExceptions` in a `write`-block would not cancel transactions, but leave it open. (Issue [#1615](https://github.com/realm/realm-kotlin/issues/1615)). - -### Compatibility -* File format: Generates Realms with file format v23. -* Realm Studio 13.0.0 or above is required to open Realms created by this version. -* This release is compatible with the following Kotlin releases: - * Kotlin 1.9.0 and above. Support for experimental K2-compilation with `kotlin.experimental.tryK2=true`. - * Ktor 2.1.2 and above. - * Coroutines 1.7.0 and above. - * AtomicFu 0.18.3 and above. - * The new memory model only. See https://github.com/realm/realm-kotlin#kotlin-memory-model-and-coroutine-compatibility -* Minimum Kbson 0.3.0. -* Minimum Gradle version: 6.8.3. -* Minimum Android Gradle Plugin version: 4.1.3. -* Minimum Android SDK: 16. -* Minimum R8: 8.0.34. - -### Internal -* None. - - ## 1.13.0 (2023-12-01) ### Breaking Changes From 0bf38958044c3e275e2f5d5fdb827a9fb5a57cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 6 Mar 2024 15:00:28 +0100 Subject: [PATCH 13/56] Included core updates in CHANGELOG --- CHANGELOG.md | 2 +- packages/external/core | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61d3f45d78..420b0d427f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,7 +87,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Minimum R8: 8.0.34. ### Internal -* Updated to Realm Core 14.1.0 commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730. +* Updated to Realm Core 14.1.0 commit 08c61e87add15b0d7fcd52c818c43fb4804e1216. ## 1.14.0 (2024-03-08) diff --git a/packages/external/core b/packages/external/core index b1d32d3d20..08c61e87ad 160000 --- a/packages/external/core +++ b/packages/external/core @@ -1 +1 @@ -Subproject commit b1d32d3d20fcb80c747aad6b37b4a9d9179e0730 +Subproject commit 08c61e87add15b0d7fcd52c818c43fb4804e1216 From dceaf9d640fe15c85187adc6bd37114b45ceb8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Wed, 6 Mar 2024 15:20:26 +0100 Subject: [PATCH 14/56] Cleanup CHANGELOG --- CHANGELOG.md | 79 ++++++++++++---------------------------------------- 1 file changed, 18 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 420b0d427f..058bff5d99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,72 +4,29 @@ This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from fileformat v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. ### Breaking changes -### Core-14.0.0 * If you want to query using @type operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types. -### Core-14.0.0-beta0 - - -* BinaryData and StringData are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a Mixed property, as now only strings will be returned. If searching for BinaryData is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. ([6407](https://github.com/realm/realm-core/issues/6407)). - -* Sorting order of strings has changed to use standard unicode codepoint order instead of grouping similar english letters together. A noticeable change will be from "aAbBzZ" to "ABZabz". ([2573](https://github.com/realm/realm-core/issues/2573)) +* Binary data and String data are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a RealmAny property, as now only strings will be returned. If searching for Binary data is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. (Core issue [realm/realm-core#6407](https://github.com/realm/realm-core/issues/6407)). +* Sorting order of strings has changed to use standard unicode codepoint order instead of grouping similar english letters together. A noticeable change will be from "aAbBzZ" to "ABZabz". (Core issue [realm/realm-core#2573](https://github.com/realm/realm-core/issues/2573)) ### Enhancements -### Core-14.1.0 -* Add support for using aggregate operations on Mixed properties in queries ([PR #7398](https://github.com/realm/realm-core/pull/7398)) -### Core-14.0.0 -* Property keypath in RQL can be substituted with value given as argument. Use '$P' in query string. (Issue [#7033](https://github.com/realm/realm-core/issues/7033)) -* You can now use query substitution for the @type argument ([#7289](https://github.com/realm/realm-core/issues/7289)) -### Core-14.0.0-beta0 -* Storage of Decimal128 properties has been optimised so that the individual values will take up 0 bits (if all nulls), 32 bits, 64 bits or 128 bits depending on what is needed. (PR [#6111](https://github.com/realm/realm-core/pull/6111)) -* Querying a specific entry in a collection (in particular 'first and 'last') is supported. (PR [#4269](https://github.com/realm/realm-core/issues/4269)) -* Index on list of strings property now supported (PR [#7142](https://github.com/realm/realm-core/pull/7142)) -### 13.27.0 - - -* Improved performance of RQL (parsed) queries on a non-linked string property using: >, >=, <, <=, operators and fixed behaviour that a null string should be evaulated as less than everything, previously nulls were not matched. ([#3939](https://github.com/realm/realm-core/issues/3939), this is a prerequisite for https://github.com/realm/realm-swift/issues/8008). -* Updated bundled OpenSSL version to 3.2.0 (PR [#7303](https://github.com/realm/realm-core/pull/7303)) - - - - +* Add support for using aggregate operations on RealmAny properties in queries (Core issue [realm/realm-core#7398](https://github.com/realm/realm-core/pull/7398)) +* Property keypath in RQL can be substituted with value given as argument. Use '$P' in query string. (Core issue [realm/realm-core#7033](https://github.com/realm/realm-core/issues/7033)) +* You can now use query substitution for the @type argument (Core issue [realm/realm-core#7289](https://github.com/realm/realm-core/issues/7289)) +* Storage of Decimal128 properties has been optimised so that the individual values will take up 0 bits (if all nulls), 32 bits, 64 bits or 128 bits depending on what is needed. (Core issue [realm/realm-core#6111](https://github.com/realm/realm-core/pull/6111)) +* Querying a specific entry in a collection (in particular 'first and 'last') is supported. (Core issue [realm/realm-core#4269](https://github.com/realm/realm-core/issues/4269)) +* Index on list of strings property now supported (Core issue [realm/realm-core#7142](https://github.com/realm/realm-core/pull/7142)) +* Improved performance of RQL (parsed) queries on a non-linked string property using: >, >=, <, <=, operators and fixed behaviour that a null string should be evaulated as less than everything, previously nulls were not matched. (Core issue [realm/realm-core#3939](https://github.com/realm/realm-core/issues/3939). +* Updated bundled OpenSSL version to 3.2.0 (Core issue [realm/realm-core#7303](https://github.com/realm/realm-core/pull/7303)) ### Fixed -### Core-14.1.0 - - - - - - - - -### Core-14.0.0 - - - - - -* `@count`/`@size` is now supported for mixed properties ([#7280](https://github.com/realm/realm-core/issues/7280), since v10.0.0) - - - - -### Core-14.0.0-beta0 - -* Fixed equality queries on a Mixed property with an index possibly returning the wrong result if values of different types happened to have the same StringIndex hash. ([6407](https://github.com/realm/realm-core/issues/6407) since v11.0.0-beta.5). -* If you have more than 8388606 links pointing to one specific object, the program will crash. ([#6577](https://github.com/realm/realm-core/issues/6577), since v6.0.0) -* Query for NULL value in Dictionary would give wrong results ([6748])(https://github.com/realm/realm-core/issues/6748), since v10.0.0) - -### 13.27.0 -* Fixed queries like `indexed_property == NONE {x}` which mistakenly matched on only x instead of not x. This only applies when an indexed property with equality (==, or IN) matches with `NONE` on a list of one item. If the constant list contained more than one value then it was working correctly. ([realm-js #7862](https://github.com/realm/realm-java/issues/7862), since v12.5.0) -* Uploading the changesets recovered during an automatic client reset recovery may lead to 'Bad server version' errors and a new client reset. ([#7279](https://github.com/realm/realm-core/issues/7279), since v13.24.1) - -* Fixed crash in fulltext index using prefix search with no matches ([#7309](https://github.com/realm/realm-core/issues/7309), since v13.18.0) - - - - -* Fix a minor race condition when backing up Realm files before a client reset which could have lead to overwriting an existing file. ([PR #7341](https://github.com/realm/realm-core/pull/7341)). +* `@count`/`@size` is now supported for `RealmAny` properties (Core issue [realm/realm-core#7280](https://github.com/realm/realm-core/issues/7280), since v10.0.0) +* Fixed equality queries on a `RealmAny` property with an index possibly returning the wrong result if values of different types happened to have the same StringIndex hash. (Core issue [realm/realm-core6407](https://github.com/realm/realm-core/issues/6407) since v11.0.0-beta.5). +* If you have more than 8388606 links pointing to one specific object, the program will crash. (Core issue [realm/realm-core#6577](https://github.com/realm/realm-core/issues/6577), since v6.0.0) +* Query for NULL value in `RealmAny` would give wrong results (Core issue [realm/realm-core6748])(https://github.com/realm/realm-core/issues/6748), since v10.0.0) +* Fixed queries like `indexed_property == NONE {x}` which mistakenly matched on only x instead of not x. This only applies when an indexed property with equality (==, or IN) matches with `NONE` on a list of one item. If the constant list contained more than one value then it was working correctly. (Core issue [realm/realm-core#7777](https://github.com/realm/realm-java/issues/7862), since v12.5.0) +* Uploading the changesets recovered during an automatic client reset recovery may lead to 'Bad server version' errors and a new client reset. (Core issue [realm/realm-core7279](https://github.com/realm/realm-core/issues/7279), since v13.24.1) +* Fixed crash in fulltext index using prefix search with no matches (Core issue [realm/realm-core#7309](https://github.com/realm/realm-core/issues/7309), since v13.18.0) +* Fix a minor race condition when backing up Realm files before a client reset which could have lead to overwriting an existing file. (Core issue [realm/realm-core#7341](https://github.com/realm/realm-core/pull/7341)). ### Compatibility * File format: Generates Realms with file format v24 (reads and upgrades file format v10 or later). From 408fe193734107ebbef91200b86895a6f63045eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Fri, 15 Mar 2024 09:28:52 +0100 Subject: [PATCH 15/56] Upgrade to Core 14.2.0 --- CHANGELOG.md | 2 +- packages/external/core | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 058bff5d99..f2f34418c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Minimum R8: 8.0.34. ### Internal -* Updated to Realm Core 14.1.0 commit 08c61e87add15b0d7fcd52c818c43fb4804e1216. +* Updated to Realm Core 14.2.0 commit 383bdc81e36293b22868ee085a6f5c265115556d. ## 1.14.0 (2024-03-08) diff --git a/packages/external/core b/packages/external/core index 08c61e87ad..383bdc81e3 160000 --- a/packages/external/core +++ b/packages/external/core @@ -1 +1 @@ -Subproject commit 08c61e87add15b0d7fcd52c818c43fb4804e1216 +Subproject commit 383bdc81e36293b22868ee085a6f5c265115556d From 5d1e73995680e84979c1a5f6b6c36f14faa39fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Fri, 15 Mar 2024 09:32:00 +0100 Subject: [PATCH 16/56] Update CHANGELOG.md Co-authored-by: clementetb --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2f34418c8..322e07202f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 1.15.0-SNAPSHOT (YYYY-MM-DD) [!NOTE] -This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from fileformat v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. +This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from file format v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. ### Breaking changes * If you want to query using @type operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types. From 496cf2ca68f826c222887a95fa826506ae7c8efa Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 7 Mar 2024 09:41:24 +0100 Subject: [PATCH 17/56] Add structure for log categories --- .../kotlin/internal/interop/RealmInterop.kt | 4 + .../kotlin/internal/interop/RealmInterop.kt | 8 +- .../kotlin/internal/interop/RealmInterop.kt | 8 +- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 121 ++++++++++++++++++ .../kotlin/io/realm/kotlin/log/LogLevel.kt | 29 +++++ .../kotlin/io/realm/kotlin/log/RealmLog.kt | 69 +++++----- .../realm/kotlin/test/common/RealmLogTests.kt | 6 + 7 files changed, 207 insertions(+), 38 deletions(-) create mode 100644 packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 6a846f05f0..b693b396eb 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -583,6 +583,10 @@ expect object RealmInterop { fun realm_set_log_level(level: CoreLogLevel) + fun realm_set_log_level_category(category: String, level: CoreLogLevel) + + fun realm_get_log_level_category(category: String): CoreLogLevel + fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, metadataMode: MetadataMode diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 58254b507c..719b992001 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -1295,9 +1295,15 @@ actual object RealmInterop { realmc.realm_set_log_level(level.priority) } + actual fun realm_set_log_level_category(category: String, level: CoreLogLevel) { + realmc.realm_set_log_level_category(category, level.priority) + } + + actual fun realm_get_log_level_category(category: String): CoreLogLevel = TODO() + actual fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, - metadataMode: MetadataMode + metadataMode: MetadataMode, ) { realmc.realm_sync_client_config_set_metadata_mode( syncClientConfig.cptr(), diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 640bd75b4e..fbfeae9241 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -2434,9 +2434,15 @@ actual object RealmInterop { realm_wrapper.realm_set_log_level(level.priority.toUInt()) } + actual fun realm_set_log_level_category(category: String, level: CoreLogLevel) { + realm_wrapper.realm_set_log_level_category(category, level.priority.toUInt()) + } + + actual fun realm_get_log_level_category(category: String): CoreLogLevel = TODO() + actual fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, - metadataMode: MetadataMode + metadataMode: MetadataMode, ) { realm_wrapper.realm_sync_client_config_set_metadata_mode( syncClientConfig.cptr(), diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt new file mode 100644 index 0000000000..23702ac538 --- /dev/null +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -0,0 +1,121 @@ +/* + * Copyright 2021 Realm 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.realm.kotlin.log + +import io.realm.kotlin.internal.interop.RealmInterop +/** + * Hierarchy + * Realm + * ├─► Storage + * │ ├─► Transaction + * │ ├─► Query + * │ ├─► Object + * │ └─► Notification + * ├─► Sync + * │ ├─► Client + * │ │ ├─► Session + * │ │ ├─► Changeset + * │ │ ├─► Network + * │ │ └─► Reset + * │ └─► Server + * ├─► App + * └─► Sdk + */ + +/** + * TODO + */ +public sealed class LogCategory( + internal val name: String, + internal val parent: LogCategory? = null +) { + internal val path: List = if (parent == null) listOf(name) else parent.path + name + private val pathAsString = path.joinToString(".") + + /** + * The current [LogLevel] for the category. Changing this will affect all registered loggers. + */ + public var level: LogLevel + get() = RealmInterop.realm_get_log_level_category(pathAsString).fromCoreLogLevel() + set(value) = RealmInterop.realm_set_log_level_category(pathAsString, value.toCoreLogLevel()) +} + +public data object StorageLogCategory : LogCategory("Storage", RealmLog) { + + /** + * TODO + */ + public val TransactionLog: LogCategory = TransactionLogCategory + /** + * TODO + */ + public val QueryLog: LogCategory = QueryLogCategory + /** + * TODO + */ + public val ObjectLog: LogCategory = ObjectLogCategory + /** + * TODO + */ + public val NotificationLog: LogCategory = NotificationLogCategory +} + + +public data object TransactionLogCategory: LogCategory("Transaction", StorageLogCategory) +public data object QueryLogCategory: LogCategory("Query", StorageLogCategory) +public data object ObjectLogCategory: LogCategory("Object", StorageLogCategory) +public data object NotificationLogCategory: LogCategory("Notification", StorageLogCategory) + + +public data object SyncLogCategory : LogCategory("Sync", RealmLog) { + /** + * TODO + */ + public val ClientLog: ClientLogCategory = ClientLogCategory + /** + * TODO + */ + public val ServerLog: LogCategory = ServerLogCategory +} + +public data object ClientLogCategory : LogCategory("Client", ClientLogCategory) { + /** + * TODO + */ + public val SessionLog: LogCategory = SessionLogCategory + /** + * TODO + */ + public val ChangesetLog: LogCategory = ChangesetLogCategory + /** + * TODO + */ + public val NetworkLog: LogCategory = NetworkLogCategory + /** + * TODO + */ + public val ResetLog: LogCategory = ResetLogCategory +} + +public data object SessionLogCategory: LogCategory("Session", ClientLogCategory) +public data object ChangesetLogCategory: LogCategory("Changeset", ClientLogCategory) +public data object NetworkLogCategory: LogCategory("Network", ClientLogCategory) +public data object ResetLogCategory: LogCategory("Reset", ClientLogCategory) +public data object ServerLogCategory: LogCategory("Server", ClientLogCategory) + + +public data object AppLogCategory: LogCategory("App", RealmLog) +public data object SdkLogCategory: LogCategory("SDK", RealmLog) \ No newline at end of file diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt index 1b6c2f804e..446b1b6c23 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt @@ -1,5 +1,6 @@ package io.realm.kotlin.log +import io.realm.kotlin.internal.interop.CoreLogLevel import io.realm.kotlin.log.LogLevel.TRACE import io.realm.kotlin.log.LogLevel.WTF @@ -20,3 +21,31 @@ public enum class LogLevel(public val priority: Int) { WTF(6), NONE(7); } + +internal fun LogLevel.toCoreLogLevel(): CoreLogLevel { + return when (this) { + LogLevel.ALL -> CoreLogLevel.RLM_LOG_LEVEL_ALL + LogLevel.TRACE -> CoreLogLevel.RLM_LOG_LEVEL_TRACE + LogLevel.DEBUG -> CoreLogLevel.RLM_LOG_LEVEL_DEBUG + LogLevel.INFO -> CoreLogLevel.RLM_LOG_LEVEL_INFO + LogLevel.WARN -> CoreLogLevel.RLM_LOG_LEVEL_WARNING + LogLevel.ERROR -> CoreLogLevel.RLM_LOG_LEVEL_ERROR + LogLevel.WTF -> CoreLogLevel.RLM_LOG_LEVEL_FATAL + LogLevel.NONE -> CoreLogLevel.RLM_LOG_LEVEL_OFF + } +} + +internal fun CoreLogLevel.fromCoreLogLevel(): LogLevel { + return when (this) { + CoreLogLevel.RLM_LOG_LEVEL_ALL, + CoreLogLevel.RLM_LOG_LEVEL_TRACE -> LogLevel.TRACE + CoreLogLevel.RLM_LOG_LEVEL_DEBUG, + CoreLogLevel.RLM_LOG_LEVEL_DETAIL -> LogLevel.DEBUG + CoreLogLevel.RLM_LOG_LEVEL_INFO -> LogLevel.INFO + CoreLogLevel.RLM_LOG_LEVEL_WARNING -> LogLevel.WARN + CoreLogLevel.RLM_LOG_LEVEL_ERROR -> LogLevel.ERROR + CoreLogLevel.RLM_LOG_LEVEL_FATAL -> LogLevel.WTF + CoreLogLevel.RLM_LOG_LEVEL_OFF -> LogLevel.NONE + else -> throw IllegalArgumentException("Invalid core log level: $this") + } +} diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index e67a9de110..92fae3e532 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -1,6 +1,22 @@ +/* + * Copyright 2023 Realm 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.realm.kotlin.log import io.realm.kotlin.Realm +import io.realm.kotlin.internal.interop.CoreLogCategory import io.realm.kotlin.internal.interop.CoreLogLevel import io.realm.kotlin.internal.interop.LogCallback import io.realm.kotlin.internal.interop.RealmInterop @@ -9,6 +25,7 @@ import io.realm.kotlin.internal.platform.createDefaultSystemLogger import io.realm.kotlin.log.RealmLog.add import io.realm.kotlin.log.RealmLog.addDefaultSystemLogger + /** * Global logger class used by all Realm components. * @@ -21,16 +38,24 @@ import io.realm.kotlin.log.RealmLog.addDefaultSystemLogger * Java. Only `%s`, `%d` and `%f` are supported. See https://stackoverflow.com/a/64499248/1389357 * and https://youtrack.jetbrains.com/issue/KT-25506 for more information. */ -public object RealmLog { +public object RealmLog : LogCategory("Realm") { /** - * The current [LogLevel]. Changing this will affect all registered loggers. + * TODO */ - public var level: LogLevel = LogLevel.WARN - set(value) { - RealmInterop.realm_set_log_level(value.toCoreLogLevel()) - field = value - } + public val StorageLog: StorageLogCategory = StorageLogCategory + /** + * TODO + */ + public val SyncLog: SyncLogCategory = SyncLogCategory + /** + * TODO + */ + public val AppLog: LogCategory = AppLogCategory + /** + * TODO + */ + public val SdkLog: LogCategory = SdkLogCategory // Lock preventing multiple threads modifying the list of loggers. private val loggersMutex = SynchronizableObject() @@ -52,7 +77,7 @@ public object RealmLog { override fun log(logLevel: Short, message: String?) { // Create concatenated up front, since Core should already filter messages // not within the log range. - val level: LogLevel = fromCoreLogLevel(CoreLogLevel.valueFromPriority(logLevel)) + val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() doLog( level, null, @@ -360,32 +385,4 @@ public object RealmLog { addDefaultSystemLogger() level = LogLevel.WARN } - - private fun LogLevel.toCoreLogLevel(): CoreLogLevel { - return when (this) { - LogLevel.ALL -> CoreLogLevel.RLM_LOG_LEVEL_ALL - LogLevel.TRACE -> CoreLogLevel.RLM_LOG_LEVEL_TRACE - LogLevel.DEBUG -> CoreLogLevel.RLM_LOG_LEVEL_DEBUG - LogLevel.INFO -> CoreLogLevel.RLM_LOG_LEVEL_INFO - LogLevel.WARN -> CoreLogLevel.RLM_LOG_LEVEL_WARNING - LogLevel.ERROR -> CoreLogLevel.RLM_LOG_LEVEL_ERROR - LogLevel.WTF -> CoreLogLevel.RLM_LOG_LEVEL_FATAL - LogLevel.NONE -> CoreLogLevel.RLM_LOG_LEVEL_OFF - } - } - - private fun fromCoreLogLevel(level: CoreLogLevel): LogLevel { - return when (level) { - CoreLogLevel.RLM_LOG_LEVEL_ALL, - CoreLogLevel.RLM_LOG_LEVEL_TRACE -> LogLevel.TRACE - CoreLogLevel.RLM_LOG_LEVEL_DEBUG, - CoreLogLevel.RLM_LOG_LEVEL_DETAIL -> LogLevel.DEBUG - CoreLogLevel.RLM_LOG_LEVEL_INFO -> LogLevel.INFO - CoreLogLevel.RLM_LOG_LEVEL_WARNING -> LogLevel.WARN - CoreLogLevel.RLM_LOG_LEVEL_ERROR -> LogLevel.ERROR - CoreLogLevel.RLM_LOG_LEVEL_FATAL -> LogLevel.WTF - CoreLogLevel.RLM_LOG_LEVEL_OFF -> LogLevel.NONE - else -> throw IllegalArgumentException("Invalid core log level: $level") - } - } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 7a2448f82f..2845e244c4 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -327,4 +327,10 @@ class RealmLogTests { fun addDefaultSystemLogger_failure() { assertFalse(RealmLog.addDefaultSystemLogger()) } + + @Test + fun setCategoryLevels() { + RealmLog.StorageLog.level = LogLevel.WARN + RealmLog.SyncLog.ClientLog.level = LogLevel.INFO + } } From 8950932acff36a488ac228f9f87da0cb55c47ec1 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 7 Mar 2024 15:17:48 +0100 Subject: [PATCH 18/56] Add tests --- .../kotlin/internal/interop/RealmInterop.kt | 2 + .../src/jvm/jni/java_class_global_def.hpp | 7 +++ .../kotlin/internal/interop/RealmInterop.kt | 8 ++- .../kotlin/internal/interop/RealmInterop.kt | 18 ++++++- packages/external/core | 2 +- .../src/main/jni/realm_api_helpers.cpp | 17 +++++++ .../src/main/jni/realm_api_helpers.h | 2 + .../kotlin/io/realm/kotlin/log/LogCategory.kt | 29 +++++------ .../kotlin/io/realm/kotlin/log/RealmLog.kt | 2 - .../realm/kotlin/test/common/RealmLogTests.kt | 51 ++++++++++++++++++- 10 files changed, 115 insertions(+), 23 deletions(-) diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index b693b396eb..83cc9d28f2 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -587,6 +587,8 @@ expect object RealmInterop { fun realm_get_log_level_category(category: String): CoreLogLevel + fun realm_get_category_names(): List + fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, metadataMode: MetadataMode diff --git a/packages/cinterop/src/jvm/jni/java_class_global_def.hpp b/packages/cinterop/src/jvm/jni/java_class_global_def.hpp index 3979de66a1..f3c32ab128 100644 --- a/packages/cinterop/src/jvm/jni/java_class_global_def.hpp +++ b/packages/cinterop/src/jvm/jni/java_class_global_def.hpp @@ -45,6 +45,7 @@ class JavaClassGlobalDef { JavaClassGlobalDef(JNIEnv* env) : m_java_util_hashmap(env, "java/util/HashMap", false) , m_java_lang_int(env, "java/lang/Integer", false) + , m_java_lang_string(env, "java/lang/String", false) , m_kotlin_jvm_functions_function0(env, "kotlin/jvm/functions/Function0", false) , m_kotlin_jvm_functions_function1(env, "kotlin/jvm/functions/Function1", false) , m_io_realm_kotlin_internal_interop_sync_network_transport(env, "io/realm/kotlin/internal/interop/sync/NetworkTransport", false) @@ -74,6 +75,7 @@ class JavaClassGlobalDef { jni_util::JavaClass m_java_util_hashmap; jni_util::JavaClass m_java_lang_int; + jni_util::JavaClass m_java_lang_string; jni_util::JavaClass m_kotlin_jvm_functions_function0; jni_util::JavaClass m_kotlin_jvm_functions_function1; jni_util::JavaClass m_io_realm_kotlin_internal_interop_sync_network_transport; @@ -133,6 +135,11 @@ class JavaClassGlobalDef { return env->NewObject(instance()->m_java_lang_int, init, value); } + inline static const jni_util::JavaClass& java_lang_string() + { + return instance()->m_java_lang_string; + } + inline static const jni_util::JavaClass& network_transport_class() { return instance()->m_io_realm_kotlin_internal_interop_sync_network_transport; diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 719b992001..0bf6ec6757 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -1299,7 +1299,13 @@ actual object RealmInterop { realmc.realm_set_log_level_category(category, level.priority) } - actual fun realm_get_log_level_category(category: String): CoreLogLevel = TODO() + actual fun realm_get_log_level_category(category: String): CoreLogLevel = + CoreLogLevel.valueFromPriority(realmc.realm_get_log_level_category(category).toShort()) + + actual fun realm_get_category_names(): List { + val names: Array = realmc.realm_get_log_category_names() as Array + return names.asList() + } actual fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index fbfeae9241..3c1e7e3d2a 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -15,6 +15,7 @@ */ // TODO https://github.com/realm/realm-kotlin/issues/889 @file:Suppress("TooGenericExceptionThrown", "TooGenericExceptionCaught") +@file:OptIn(ExperimentalForeignApi::class) package io.realm.kotlin.internal.interop @@ -54,6 +55,7 @@ import kotlinx.cinterop.CPointerVar import kotlinx.cinterop.CPointerVarOf import kotlinx.cinterop.CValue import kotlinx.cinterop.CVariable +import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.LongVar import kotlinx.cinterop.MemScope import kotlinx.cinterop.StableRef @@ -2438,7 +2440,21 @@ actual object RealmInterop { realm_wrapper.realm_set_log_level_category(category, level.priority.toUInt()) } - actual fun realm_get_log_level_category(category: String): CoreLogLevel = TODO() + actual fun realm_get_log_level_category(category: String): CoreLogLevel = + CoreLogLevel.valueFromPriority(realm_wrapper.realm_get_log_level_category(category).toShort()) + +// public external expect fun realm_get_category_names(num_values: platform.posix.size_t /* = kotlin.ULong */, out_values: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } + actual fun realm_get_category_names(): List { + memScoped { + val namesCount = realm_wrapper.realm_get_category_names(0u, null) + val namesBuffer = allocArray>(namesCount.toInt()) + realm_wrapper.realm_get_category_names(namesCount, namesBuffer) + + return List(namesCount.toInt()) { + namesBuffer[it].safeKString() + } + } + } actual fun realm_sync_client_config_set_metadata_mode( syncClientConfig: RealmSyncClientConfigurationPointer, diff --git a/packages/external/core b/packages/external/core index 383bdc81e3..6491844109 160000 --- a/packages/external/core +++ b/packages/external/core @@ -1 +1 @@ -Subproject commit 383bdc81e36293b22868ee085a6f5c265115556d +Subproject commit 6491844109bd299e82520f54d70101cb6a8fbae3 diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp index 54522828ba..c9524f1f53 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp @@ -1371,3 +1371,20 @@ realm_class_info_t_cleanup(realm_class_info_t * value) { delete[] value->primary_key; delete[] value->name; } + +jobjectArray realm_get_log_category_names() { + JNIEnv* env = get_env(true); + + size_t bufferSize = 50; + const char* category_names[bufferSize]; + size_t namesCount = realm_get_category_names(bufferSize, category_names); + + auto array = env->NewObjectArray(namesCount, JavaClassGlobalDef::java_lang_string(), nullptr); + + for(size_t i = 0; i < namesCount; i++) { + jstring string = env->NewStringUTF(category_names[i]); + env->SetObjectArrayElement(array, i, string); + } + + return array; +} diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h index 84caf586dc..37d1347d68 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h @@ -161,4 +161,6 @@ bool realm_sync_websocket_message(int64_t observer_ptr, jbyteArray data, size_t void realm_sync_websocket_closed(int64_t observer_ptr, bool was_clean, int error_code, const char* reason); +jobjectArray realm_get_log_category_names(); + #endif //TEST_REALM_API_HELPERS_H diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 23702ac538..ac44b59a41 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -43,7 +43,7 @@ public sealed class LogCategory( internal val parent: LogCategory? = null ) { internal val path: List = if (parent == null) listOf(name) else parent.path + name - private val pathAsString = path.joinToString(".") + internal val pathAsString = path.joinToString(".") /** * The current [LogLevel] for the category. Changing this will affect all registered loggers. @@ -73,12 +73,10 @@ public data object StorageLogCategory : LogCategory("Storage", RealmLog) { public val NotificationLog: LogCategory = NotificationLogCategory } - -public data object TransactionLogCategory: LogCategory("Transaction", StorageLogCategory) -public data object QueryLogCategory: LogCategory("Query", StorageLogCategory) -public data object ObjectLogCategory: LogCategory("Object", StorageLogCategory) -public data object NotificationLogCategory: LogCategory("Notification", StorageLogCategory) - +public data object TransactionLogCategory : LogCategory("Transaction", StorageLogCategory) +public data object QueryLogCategory : LogCategory("Query", StorageLogCategory) +public data object ObjectLogCategory : LogCategory("Object", StorageLogCategory) +public data object NotificationLogCategory : LogCategory("Notification", StorageLogCategory) public data object SyncLogCategory : LogCategory("Sync", RealmLog) { /** @@ -91,7 +89,7 @@ public data object SyncLogCategory : LogCategory("Sync", RealmLog) { public val ServerLog: LogCategory = ServerLogCategory } -public data object ClientLogCategory : LogCategory("Client", ClientLogCategory) { +public data object ClientLogCategory : LogCategory("Client", SyncLogCategory) { /** * TODO */ @@ -110,12 +108,11 @@ public data object ClientLogCategory : LogCategory("Client", ClientLogCategory) public val ResetLog: LogCategory = ResetLogCategory } -public data object SessionLogCategory: LogCategory("Session", ClientLogCategory) -public data object ChangesetLogCategory: LogCategory("Changeset", ClientLogCategory) -public data object NetworkLogCategory: LogCategory("Network", ClientLogCategory) -public data object ResetLogCategory: LogCategory("Reset", ClientLogCategory) -public data object ServerLogCategory: LogCategory("Server", ClientLogCategory) - +public data object SessionLogCategory : LogCategory("Session", ClientLogCategory) +public data object ChangesetLogCategory : LogCategory("Changeset", ClientLogCategory) +public data object NetworkLogCategory : LogCategory("Network", ClientLogCategory) +public data object ResetLogCategory : LogCategory("Reset", ClientLogCategory) +public data object ServerLogCategory : LogCategory("Server", SyncLogCategory) -public data object AppLogCategory: LogCategory("App", RealmLog) -public data object SdkLogCategory: LogCategory("SDK", RealmLog) \ No newline at end of file +public data object AppLogCategory : LogCategory("App", RealmLog) +public data object SdkLogCategory : LogCategory("SDK", RealmLog) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 92fae3e532..0ec57bf436 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -16,7 +16,6 @@ package io.realm.kotlin.log import io.realm.kotlin.Realm -import io.realm.kotlin.internal.interop.CoreLogCategory import io.realm.kotlin.internal.interop.CoreLogLevel import io.realm.kotlin.internal.interop.LogCallback import io.realm.kotlin.internal.interop.RealmInterop @@ -25,7 +24,6 @@ import io.realm.kotlin.internal.platform.createDefaultSystemLogger import io.realm.kotlin.log.RealmLog.add import io.realm.kotlin.log.RealmLog.addDefaultSystemLogger - /** * Global logger class used by all Realm components. * diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 2845e244c4..cafe468c43 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -16,6 +16,7 @@ @file:Suppress("invisible_reference", "invisible_member") package io.realm.kotlin.test.common +import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger @@ -25,6 +26,7 @@ import kotlinx.atomicfu.atomic import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test +import kotlin.test.assertContains import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNull @@ -43,6 +45,30 @@ class RealmLogTests { private lateinit var existingLogLevel: LogLevel private lateinit var log: RealmLog + private val logCategories = listOf( + RealmLog, + + RealmLog.StorageLog, + RealmLog.SyncLog, + + RealmLog.SyncLog.ClientLog, + + RealmLog.SyncLog.ClientLog.SessionLog, + RealmLog.SyncLog.ClientLog.ChangesetLog, + RealmLog.SyncLog.ClientLog.NetworkLog, + RealmLog.SyncLog.ClientLog.ResetLog, + + RealmLog.SyncLog.ServerLog, + + RealmLog.AppLog, + RealmLog.SdkLog, + + RealmLog.StorageLog.TransactionLog, + RealmLog.StorageLog.QueryLog, + RealmLog.StorageLog.ObjectLog, + RealmLog.StorageLog.NotificationLog, + ) + @BeforeTest fun setUp() { existingLogLevel = RealmLog.level @@ -330,7 +356,28 @@ class RealmLogTests { @Test fun setCategoryLevels() { - RealmLog.StorageLog.level = LogLevel.WARN - RealmLog.SyncLog.ClientLog.level = LogLevel.INFO + logCategories.forEach { logCategory -> + val previousLevel: LogLevel = logCategory.level + logCategory.level = LogLevel.TRACE + assertEquals(LogLevel.TRACE, logCategory.level) + + // Restore the level to whatever it was set before + logCategory.level = previousLevel + } + } + + @Test + fun categoriesWatchdog() { + val coreLogCategoryNames = RealmInterop.realm_get_category_names() + + val logCategoriesPaths = logCategories.map { it.pathAsString } + + logCategoriesPaths.forEach { path -> + assertContains(coreLogCategoryNames, path) + } + + coreLogCategoryNames.forEach { path -> + assertContains(logCategoriesPaths, path) + } } } From f797f604619fcc3458ca8779a01d89285b9dfa54 Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 13 Mar 2024 11:48:31 +0100 Subject: [PATCH 19/56] Add setters/getters --- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 62 +++++++++++++------ .../kotlin/io/realm/kotlin/log/RealmLog.kt | 37 ++++++----- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 8 +++ .../realm/kotlin/test/common/RealmLogTests.kt | 51 +++++++-------- 4 files changed, 96 insertions(+), 62 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index ac44b59a41..e584a676d2 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -35,6 +35,8 @@ import io.realm.kotlin.internal.interop.RealmInterop * └─► Sdk */ + + /** * TODO */ @@ -45,32 +47,56 @@ public sealed class LogCategory( internal val path: List = if (parent == null) listOf(name) else parent.path + name internal val pathAsString = path.joinToString(".") + public companion object { + internal fun fromCoreValue(category: String): LogCategory { + TODO("Not yet implemented") + } + + public val Realm: RealmLogCategory = RealmLogCategory + } +} + +public data object RealmLogCategory: LogCategory("Realm") { + + /** + * TODO + */ + public val Storage:StorageLogCategory = StorageLogCategory + /** - * The current [LogLevel] for the category. Changing this will affect all registered loggers. + * TODO + */ + public val Sync:SyncLogCategory = SyncLogCategory + + /** + * TODO + */ + public val App:LogCategory = AppLogCategory + + /** + * TODO */ - public var level: LogLevel - get() = RealmInterop.realm_get_log_level_category(pathAsString).fromCoreLogLevel() - set(value) = RealmInterop.realm_set_log_level_category(pathAsString, value.toCoreLogLevel()) + public val Sdk:LogCategory = SdkLogCategory } -public data object StorageLogCategory : LogCategory("Storage", RealmLog) { +public data object StorageLogCategory : LogCategory("Storage", RealmLogCategory) { /** * TODO */ - public val TransactionLog: LogCategory = TransactionLogCategory + public val Transaction:LogCategory = TransactionLogCategory /** * TODO */ - public val QueryLog: LogCategory = QueryLogCategory + public val Query:LogCategory = QueryLogCategory /** * TODO */ - public val ObjectLog: LogCategory = ObjectLogCategory + public val Object:LogCategory = ObjectLogCategory /** * TODO */ - public val NotificationLog: LogCategory = NotificationLogCategory + public val Notification:LogCategory = NotificationLogCategory } public data object TransactionLogCategory : LogCategory("Transaction", StorageLogCategory) @@ -78,34 +104,34 @@ public data object QueryLogCategory : LogCategory("Query", StorageLogCategory) public data object ObjectLogCategory : LogCategory("Object", StorageLogCategory) public data object NotificationLogCategory : LogCategory("Notification", StorageLogCategory) -public data object SyncLogCategory : LogCategory("Sync", RealmLog) { +public data object SyncLogCategory : LogCategory("Sync", RealmLogCategory) { /** * TODO */ - public val ClientLog: ClientLogCategory = ClientLogCategory + public val Client:ClientLogCategory = ClientLogCategory /** * TODO */ - public val ServerLog: LogCategory = ServerLogCategory + public val Server:LogCategory = ServerLogCategory } public data object ClientLogCategory : LogCategory("Client", SyncLogCategory) { /** * TODO */ - public val SessionLog: LogCategory = SessionLogCategory + public val Session:LogCategory = SessionLogCategory /** * TODO */ - public val ChangesetLog: LogCategory = ChangesetLogCategory + public val Changeset:LogCategory = ChangesetLogCategory /** * TODO */ - public val NetworkLog: LogCategory = NetworkLogCategory + public val Network:LogCategory = NetworkLogCategory /** * TODO */ - public val ResetLog: LogCategory = ResetLogCategory + public val Reset:LogCategory = ResetLogCategory } public data object SessionLogCategory : LogCategory("Session", ClientLogCategory) @@ -114,5 +140,5 @@ public data object NetworkLogCategory : LogCategory("Network", ClientLogCategory public data object ResetLogCategory : LogCategory("Reset", ClientLogCategory) public data object ServerLogCategory : LogCategory("Server", SyncLogCategory) -public data object AppLogCategory : LogCategory("App", RealmLog) -public data object SdkLogCategory : LogCategory("SDK", RealmLog) +public data object AppLogCategory : LogCategory("App", RealmLogCategory) +public data object SdkLogCategory : LogCategory("SDK", RealmLogCategory) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 0ec57bf436..5cb3f5562a 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -36,24 +36,7 @@ import io.realm.kotlin.log.RealmLog.addDefaultSystemLogger * Java. Only `%s`, `%d` and `%f` are supported. See https://stackoverflow.com/a/64499248/1389357 * and https://youtrack.jetbrains.com/issue/KT-25506 for more information. */ -public object RealmLog : LogCategory("Realm") { - - /** - * TODO - */ - public val StorageLog: StorageLogCategory = StorageLogCategory - /** - * TODO - */ - public val SyncLog: SyncLogCategory = SyncLogCategory - /** - * TODO - */ - public val AppLog: LogCategory = AppLogCategory - /** - * TODO - */ - public val SdkLog: LogCategory = SdkLogCategory +public object RealmLog { // Lock preventing multiple threads modifying the list of loggers. private val loggersMutex = SynchronizableObject() @@ -67,7 +50,23 @@ public object RealmLog : LogCategory("Realm") { // copy this reference before using it. private var loggers: MutableList = mutableListOf() - init { + /** + * The current [LogLevel]. Changing this will affect all registered loggers. + */ + public var level: LogLevel + get() = getLevel(LogCategory.Realm) + set(value) = setLevel(value, LogCategory.Realm) + + + public fun setLevel(level: LogLevel, category: LogCategory = LogCategory.Realm) { + RealmInterop.realm_set_log_level_category(category.pathAsString, level.toCoreLogLevel()) + } + + public fun getLevel(category: LogCategory): LogLevel = + RealmInterop.realm_get_log_level_category(category.pathAsString).fromCoreLogLevel() + + + init { addDefaultSystemLogger() RealmInterop.realm_set_log_callback( level.toCoreLogLevel(), diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index 379a906045..9c4189f2bf 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -38,6 +38,14 @@ public interface RealmLogger { /** * Log an event. */ + public fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + log(level, throwable, message, args) + } + + /** + * Log an event. + */ + @Deprecated("Use log with category instead", ReplaceWith("log")) public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) /** diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index cafe468c43..28545ec395 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -17,6 +17,7 @@ package io.realm.kotlin.test.common import io.realm.kotlin.internal.interop.RealmInterop +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger @@ -46,27 +47,27 @@ class RealmLogTests { private lateinit var log: RealmLog private val logCategories = listOf( - RealmLog, + LogCategory.Realm, - RealmLog.StorageLog, - RealmLog.SyncLog, + LogCategory.Realm.Storage, + LogCategory.Realm.Sync, - RealmLog.SyncLog.ClientLog, + LogCategory.Realm.Sync.Client, - RealmLog.SyncLog.ClientLog.SessionLog, - RealmLog.SyncLog.ClientLog.ChangesetLog, - RealmLog.SyncLog.ClientLog.NetworkLog, - RealmLog.SyncLog.ClientLog.ResetLog, + LogCategory.Realm.Sync.Client.Session, + LogCategory.Realm.Sync.Client.Changeset, + LogCategory.Realm.Sync.Client.Network, + LogCategory.Realm.Sync.Client.Reset, - RealmLog.SyncLog.ServerLog, + LogCategory.Realm.Sync.Server, - RealmLog.AppLog, - RealmLog.SdkLog, + LogCategory.Realm.App, + LogCategory.Realm.Sdk, - RealmLog.StorageLog.TransactionLog, - RealmLog.StorageLog.QueryLog, - RealmLog.StorageLog.ObjectLog, - RealmLog.StorageLog.NotificationLog, + LogCategory.Realm.Storage.Transaction, + LogCategory.Realm.Storage.Query, + LogCategory.Realm.Storage.Object, + LogCategory.Realm.Storage.Notification, ) @BeforeTest @@ -127,7 +128,7 @@ class RealmLogTests { @Test fun smallLogEntry() { val message = "Testing the RealmLog implementation" - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(message) @@ -146,7 +147,7 @@ class RealmLogTests { fun smallLogEntryWithArgs() { val message = "Testing the RealmLog implementation: (%s, %d, %f)" val args: Array = arrayOf("foo", Long.MAX_VALUE, Float.MAX_VALUE) - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(message, *args) @@ -164,7 +165,7 @@ class RealmLogTests { @Test fun longLogEntry() { val message = Utils.createRandomString(8000) - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(message) @@ -183,7 +184,7 @@ class RealmLogTests { fun longLogEntryWithArgs() { val message = "${Utils.createRandomString(8000)}: (%s, %d, %f)" val args: Array = arrayOf("foo", Long.MAX_VALUE, Float.MAX_VALUE) - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(message, *args) @@ -201,7 +202,7 @@ class RealmLogTests { @Test fun logException() { val error = IllegalArgumentException("BOOM") - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(error) @@ -221,7 +222,7 @@ class RealmLogTests { val error = IllegalArgumentException("BOOM") val message = "Details: (%s, %d, %f)" val args: Array = arrayOf("foo", Long.MAX_VALUE, Float.MAX_VALUE) - LogLevel.values().forEach { + LogLevel.entries.forEach { when (it) { LogLevel.ALL -> { /* Ignore */ } LogLevel.TRACE -> log.trace(error, message, *args) @@ -357,12 +358,12 @@ class RealmLogTests { @Test fun setCategoryLevels() { logCategories.forEach { logCategory -> - val previousLevel: LogLevel = logCategory.level - logCategory.level = LogLevel.TRACE - assertEquals(LogLevel.TRACE, logCategory.level) + val previousLevel: LogLevel = RealmLog.getLevel(logCategory) + RealmLog.setLevel(LogLevel.TRACE, logCategory) + assertEquals(LogLevel.TRACE, RealmLog.getLevel(logCategory)) // Restore the level to whatever it was set before - logCategory.level = previousLevel + RealmLog.setLevel(previousLevel, logCategory) } } From ea211deb037b84c03c573631a7b4b747b2f437f9 Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 13 Mar 2024 14:06:00 +0100 Subject: [PATCH 20/56] Pass category in logs callback --- .../realm/kotlin/internal/interop/Callback.kt | 2 +- .../kotlin/internal/interop/RealmInterop.kt | 4 +- .../src/main/jni/realm_api_helpers.cpp | 6 +- .../io/realm/kotlin/internal/ContextLogger.kt | 5 +- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 58 ++++++++++++------- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 48 +++++++-------- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 4 +- .../io/realm/kotlin/test/common/RealmTests.kt | 2 + 8 files changed, 76 insertions(+), 53 deletions(-) diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/Callback.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/Callback.kt index 4d262f206d..901f7db411 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/Callback.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/Callback.kt @@ -43,7 +43,7 @@ interface SyncSessionTransferCompletionCallback { interface LogCallback { // Passes core log levels as shorts to avoid unnecessary jumping between the SDK and JNI - fun log(logLevel: Short, message: String?) + fun log(categoryValue: String, logLevel: Short, message: String?) } interface SyncBeforeClientResetHandler { diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 3c1e7e3d2a..ad6a9a41cb 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -2422,9 +2422,9 @@ actual object RealmInterop { actual fun realm_set_log_callback(level: CoreLogLevel, callback: LogCallback) { realm_wrapper.realm_set_log_callback( - staticCFunction { userData, logLevel, message -> + staticCFunction { userData, category, logLevel, message -> val userDataLogCallback = safeUserData(userData) - userDataLogCallback.log(logLevel.toShort(), message?.toKString()) + userDataLogCallback.log(category!!.toKString(), logLevel.toShort(), message?.toKString()) }, level.priority.toUInt(), StableRef.create(callback).asCPointer(), diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp index c9524f1f53..7ce3eb9fa5 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp @@ -962,7 +962,7 @@ realm_sync_socket_t* realm_sync_websocket_new(int64_t sync_client_config_ptr, jo void set_log_callback(jint j_log_level, jobject log_callback) { auto jenv = get_env(false); auto log_level = static_cast(j_log_level); -realm_set_log_callback([](void *userdata, realm_log_level_e level, const char *message) { +realm_set_log_callback([](void *userdata, const char *category, realm_log_level_e level, const char *message) { auto log_callback = static_cast(userdata); auto jenv = get_env(true); @@ -971,10 +971,10 @@ realm_set_log_callback([](void *userdata, realm_log_level_e level, const char *m static JavaMethod log_method(jenv, JavaClassGlobalDef::log_callback(), "log", - "(SLjava/lang/String;)V"); + "(Ljava/lang/String;SLjava/lang/String;)V"); push_local_frame(jenv, 1); - jenv->CallVoidMethod(log_callback, log_method, java_level, to_jstring(jenv, message)); + jenv->CallVoidMethod(log_callback, log_method, to_jstring(jenv, category), java_level, to_jstring(jenv, message)); jni_check_exception(jenv); jenv->PopLocalFrame(NULL); }, diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt index 854d6321bf..dc92aac7af 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt @@ -1,5 +1,6 @@ package io.realm.kotlin.internal +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog @@ -81,10 +82,10 @@ public class ContextLogger(public val context: String? = null) { } private inline fun doLog(level: LogLevel, throwable: Throwable?) { - RealmLog.doLog(level, throwable, null) + RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, null) } private inline fun doLog(level: LogLevel, throwable: Throwable?, message: () -> String?, vararg args: Any?) { - RealmLog.doLog(level, throwable, message, *args) + RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index e584a676d2..c206d2fc7e 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -15,7 +15,6 @@ */ package io.realm.kotlin.log -import io.realm.kotlin.internal.interop.RealmInterop /** * Hierarchy * Realm @@ -36,47 +35,59 @@ import io.realm.kotlin.internal.interop.RealmInterop */ - /** * TODO */ public sealed class LogCategory( internal val name: String, - internal val parent: LogCategory? = null + internal val parent: LogCategory? = null, ) { internal val path: List = if (parent == null) listOf(name) else parent.path + name internal val pathAsString = path.joinToString(".") + internal val children: MutableMap = mutableMapOf() + + init { + parent?.children?.put(name, this) + } public companion object { - internal fun fromCoreValue(category: String): LogCategory { - TODO("Not yet implemented") + internal fun fromCoreValue(categoryValue: String): LogCategory { + val path = categoryValue.split(".").asSequence() + + var category :LogCategory = Realm + + path.onEach { nextElement -> + category = category.children[nextElement]!! + } + + return category } public val Realm: RealmLogCategory = RealmLogCategory } } -public data object RealmLogCategory: LogCategory("Realm") { +public data object RealmLogCategory : LogCategory("Realm") { /** * TODO */ - public val Storage:StorageLogCategory = StorageLogCategory + public val Storage: StorageLogCategory = StorageLogCategory /** * TODO */ - public val Sync:SyncLogCategory = SyncLogCategory + public val Sync: SyncLogCategory = SyncLogCategory /** * TODO */ - public val App:LogCategory = AppLogCategory + public val App: LogCategory = AppLogCategory /** * TODO */ - public val Sdk:LogCategory = SdkLogCategory + public val Sdk: LogCategory = SdkLogCategory } public data object StorageLogCategory : LogCategory("Storage", RealmLogCategory) { @@ -84,19 +95,22 @@ public data object StorageLogCategory : LogCategory("Storage", RealmLogCategory) /** * TODO */ - public val Transaction:LogCategory = TransactionLogCategory + public val Transaction: LogCategory = TransactionLogCategory + /** * TODO */ - public val Query:LogCategory = QueryLogCategory + public val Query: LogCategory = QueryLogCategory + /** * TODO */ - public val Object:LogCategory = ObjectLogCategory + public val Object: LogCategory = ObjectLogCategory + /** * TODO */ - public val Notification:LogCategory = NotificationLogCategory + public val Notification: LogCategory = NotificationLogCategory } public data object TransactionLogCategory : LogCategory("Transaction", StorageLogCategory) @@ -108,30 +122,34 @@ public data object SyncLogCategory : LogCategory("Sync", RealmLogCategory) { /** * TODO */ - public val Client:ClientLogCategory = ClientLogCategory + public val Client: ClientLogCategory = ClientLogCategory + /** * TODO */ - public val Server:LogCategory = ServerLogCategory + public val Server: LogCategory = ServerLogCategory } public data object ClientLogCategory : LogCategory("Client", SyncLogCategory) { /** * TODO */ - public val Session:LogCategory = SessionLogCategory + public val Session: LogCategory = SessionLogCategory + /** * TODO */ - public val Changeset:LogCategory = ChangesetLogCategory + public val Changeset: LogCategory = ChangesetLogCategory + /** * TODO */ - public val Network:LogCategory = NetworkLogCategory + public val Network: LogCategory = NetworkLogCategory + /** * TODO */ - public val Reset:LogCategory = ResetLogCategory + public val Reset: LogCategory = ResetLogCategory } public data object SessionLogCategory : LogCategory("Session", ClientLogCategory) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 5cb3f5562a..03c22ecb65 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -71,11 +71,13 @@ public object RealmLog { RealmInterop.realm_set_log_callback( level.toCoreLogLevel(), object : LogCallback { - override fun log(logLevel: Short, message: String?) { + override fun log(categoryValue: String, logLevel: Short, message: String?) { // Create concatenated up front, since Core should already filter messages // not within the log range. + val category: LogCategory = LogCategory.fromCoreValue(categoryValue) val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() doLog( + category, level, null, if (message.isNullOrBlank()) { null } else { "[Core] $message" } @@ -160,7 +162,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun trace(throwable: Throwable?) { - doLog(LogLevel.TRACE, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, throwable, null) } /** @@ -172,7 +174,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.TRACE, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, throwable, message, *args) } /** @@ -183,7 +185,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(message: String, vararg args: Any?) { - doLog(LogLevel.TRACE, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, null, message, *args) } /** @@ -192,7 +194,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun debug(throwable: Throwable?) { - doLog(LogLevel.DEBUG, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable, null) } /** @@ -204,7 +206,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.DEBUG, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable, message, *args) } /** @@ -215,7 +217,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(message: String, vararg args: Any?) { - doLog(LogLevel.DEBUG, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, null, message, *args) } /** @@ -224,7 +226,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun info(throwable: Throwable?) { - doLog(LogLevel.INFO, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.INFO, throwable, null) } /** @@ -236,7 +238,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.INFO, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.INFO, throwable, message, *args) } /** @@ -247,7 +249,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(message: String, vararg args: Any?) { - doLog(LogLevel.INFO, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.INFO, null, message, *args) } /** @@ -256,7 +258,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun warn(throwable: Throwable?) { - doLog(LogLevel.WARN, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.WARN, throwable, null) } /** @@ -268,7 +270,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.WARN, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.WARN, throwable, message, *args) } /** @@ -279,7 +281,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(message: String, vararg args: Any?) { - doLog(LogLevel.WARN, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.WARN, null, message, *args) } /** @@ -288,7 +290,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun error(throwable: Throwable?) { - doLog(LogLevel.ERROR, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, throwable, null) } /** @@ -300,7 +302,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.ERROR, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, throwable, message, *args) } /** @@ -311,7 +313,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(message: String, vararg args: Any?) { - doLog(LogLevel.ERROR, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, null, message, *args) } /** @@ -320,7 +322,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun wtf(throwable: Throwable?) { - doLog(LogLevel.WTF, throwable, null) + doLog(LogCategory.Realm.Sdk, LogLevel.WTF, throwable, null) } /** @@ -332,7 +334,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.WTF, throwable, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.WTF, throwable, message, *args) } /** @@ -343,18 +345,18 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(message: String, vararg args: Any?) { - doLog(LogLevel.WTF, null, message, *args) + doLog(LogCategory.Realm.Sdk, LogLevel.WTF, null, message, *args) } /** * Log a message. */ - internal fun doLog(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { if (level.priority >= this.level.priority) { // Copy the reference to loggers so they are stable while iterating them. val loggers = this.loggers loggers.forEach { - it.log(level, throwable, message, *args) + it.log(category, level, throwable, message, *args) } } } @@ -363,13 +365,13 @@ public object RealmLog { * Internal method used to optimize logging from internal components. See * [io.realm.kotlin.internal.ContextLogger] for more details. */ - internal inline fun doLog(level: LogLevel, throwable: Throwable?, message: () -> String?, vararg args: Any?) { + internal inline fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: () -> String?, vararg args: Any?) { if (level.priority >= this.level.priority) { // Copy the reference to loggers so they are stable while iterating them. val loggers = this.loggers val msg = message() loggers.forEach { - it.log(level, throwable, msg, *args) + it.log(category, level, throwable, msg, *args) } } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index 9c4189f2bf..ecae903616 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -39,7 +39,7 @@ public interface RealmLogger { * Log an event. */ public fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - log(level, throwable, message, args) + log(level, throwable, message, *args) } /** @@ -52,6 +52,6 @@ public interface RealmLogger { * Log an event. */ public fun log(level: LogLevel, message: String) { - log(level, null, message) + log(LogCategory.Realm.Sdk, level, null, message) } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index 5bf65df413..2398fa27bc 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,6 +28,8 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf +import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils From 1b75cd92736334bb94cccf5a885917f1e8fbc242 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 14 Mar 2024 13:29:54 +0100 Subject: [PATCH 21/56] Propagate log category in callbacks --- packages/gradle-plugin/build.gradle.kts | 4 ++-- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 20 ++++++------------- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 8 ++++++-- .../kotlin/internal/platform/StdOutLogger.kt | 3 ++- .../kotlin/internal/platform/NSLogLogger.kt | 3 ++- .../io/realm/kotlin/test/util/TestLogger.kt | 9 ++++++++- .../test/common/RealmConfigurationTests.kt | 2 +- .../kotlin/test/mongodb/util/HttpClient.kt | 3 ++- 8 files changed, 29 insertions(+), 23 deletions(-) diff --git a/packages/gradle-plugin/build.gradle.kts b/packages/gradle-plugin/build.gradle.kts index 09ac559bbd..02981c1983 100644 --- a/packages/gradle-plugin/build.gradle.kts +++ b/packages/gradle-plugin/build.gradle.kts @@ -96,14 +96,14 @@ sourceSets { // Task to generate gradle plugin runtime constants for SDK and core versions tasks.create("versionConstants") { val coreDependenciesFile = layout.projectDirectory.file( - listOf("..", "external", "core", "dependencies.list").joinToString(File.separator) + listOf("..", "external", "core", "dependencies.yml").joinToString(File.separator) ) val outputDir = file(versionDirectory) inputs.property("version", project.version) inputs.file(coreDependenciesFile) outputs.dir(outputDir) - val versionRegex = "^VERSION=(.*)\$".toRegex() + val versionRegex = "^VERSION: (.*)\$".toRegex() val coreVersion = providers.fileContents(coreDependenciesFile).asText.get().lineSequence() .map { dependecy -> versionRegex.find(dependecy)?.groups?.get(1)?.value }.single { it != null } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index c206d2fc7e..7828479e94 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -34,6 +34,9 @@ package io.realm.kotlin.log * └─► Sdk */ +// It cannot reside in the LogCategory companion because it would not be initialized +// when we register categories. +private val categoriesByPath: MutableMap = mutableMapOf() /** * TODO @@ -44,26 +47,15 @@ public sealed class LogCategory( ) { internal val path: List = if (parent == null) listOf(name) else parent.path + name internal val pathAsString = path.joinToString(".") - internal val children: MutableMap = mutableMapOf() init { - parent?.children?.put(name, this) + categoriesByPath[name] = this } public companion object { - internal fun fromCoreValue(categoryValue: String): LogCategory { - val path = categoryValue.split(".").asSequence() - - var category :LogCategory = Realm - - path.onEach { nextElement -> - category = category.children[nextElement]!! - } - - return category - } - public val Realm: RealmLogCategory = RealmLogCategory + + internal fun fromCoreValue(categoryPath: String): LogCategory = LogCategory.Realm //categoriesByPath[categoryPath]!! } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index ecae903616..bdeb98f212 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -28,6 +28,7 @@ public interface RealmLogger { /** * The [LogLevel] used in this logger. */ + @Deprecated("No longer in use") public val level: LogLevel /** @@ -45,12 +46,15 @@ public interface RealmLogger { /** * Log an event. */ - @Deprecated("Use log with category instead", ReplaceWith("log")) - public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) + @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) + public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + log(level, message!!) + } /** * Log an event. */ + @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) public fun log(level: LogLevel, message: String) { log(LogCategory.Realm.Sdk, level, null, message) } diff --git a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt index f0855ac686..36111e3c19 100644 --- a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt +++ b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt @@ -15,6 +15,7 @@ */ package io.realm.kotlin.internal.platform +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import java.io.PrintWriter @@ -32,7 +33,7 @@ internal class StdOutLogger( override val level: LogLevel ) : RealmLogger { - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { val logMessage: String = prepareLogMessage(throwable, message, *args) val timestamp: String = getTimestamp() println("$timestamp ${level.name}: [$tag] $logMessage") diff --git a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt index 3cc3d6cdf5..e0ef474a37 100644 --- a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt +++ b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt @@ -15,6 +15,7 @@ */ package io.realm.kotlin.internal.platform +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import platform.Foundation.NSLog @@ -31,7 +32,7 @@ internal class NSLogLogger( override val level: LogLevel ) : RealmLogger { - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { val logMessage: String = prepareLogMessage(throwable, message, *args) NSLog("%s: [%s] %s", level.name, tag, logMessage) } diff --git a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt index e87ee84a0d..c825ca7382 100644 --- a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt +++ b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt @@ -1,5 +1,6 @@ package io.realm.kotlin.test.util +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger @@ -13,11 +14,17 @@ class TestLogger : RealmLogger { var throwable: Throwable? = null var message: String? = null var args: Array = arrayOf() + private lateinit var category: LogCategory - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + this.category = category this.logLevel = level this.throwable = throwable this.message = message this.args = args } + + override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + TODO("Not yet implemented") + } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index b84b0226d6..953318856f 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -246,7 +246,7 @@ class RealmConfigurationTests { fun defaultLogLevel() { val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) .build() - assertEquals(LogLevel.WARN, config.log.level) + assertEquals(LogLevel.INFO, config.log.level) } @Test diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt index da9e02c6e7..edbcedb4af 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt @@ -25,6 +25,7 @@ import io.ktor.client.plugins.logging.Logger import io.ktor.client.plugins.logging.Logging import io.ktor.serialization.kotlinx.json.json import io.realm.kotlin.internal.platform.createDefaultSystemLogger +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.mongodb.internal.createPlatformClient import kotlinx.serialization.json.Json @@ -59,7 +60,7 @@ fun defaultClient(name: String, debug: Boolean, block: HttpClientConfig<*>.() -> // TODO Hook up with AppConfiguration/RealmConfiguration logger private val logger = createDefaultSystemLogger(name) override fun log(message: String) { - logger.log(LogLevel.DEBUG, throwable = null, message = message) + logger.log(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable = null, message = message) } } level = io.ktor.client.plugins.logging.LogLevel.ALL From 668a6185182687c8eb3a29706280c7c49397457b Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 14 Mar 2024 23:11:09 +0100 Subject: [PATCH 22/56] Fix compile issues on darwin --- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 80 ++++++++++++------- .../kotlin/io/realm/kotlin/log/LogLevel.kt | 2 +- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 16 ++-- .../io/realm/kotlin/test/util/TestLogger.kt | 4 - .../test/common/RealmConfigurationTests.kt | 4 +- .../realm/kotlin/test/common/RealmLogTests.kt | 2 +- .../io/realm/kotlin/test/common/RealmTests.kt | 2 - 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 7828479e94..67ca84598f 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -34,33 +34,38 @@ package io.realm.kotlin.log * └─► Sdk */ -// It cannot reside in the LogCategory companion because it would not be initialized -// when we register categories. private val categoriesByPath: MutableMap = mutableMapOf() - +internal fun newCategory( + name: String, + parent: LogCategory? = null, +): LogCategory = LogCategoryImpl(name, parent).also { category -> + categoriesByPath["$category"] = category +} /** * TODO */ -public sealed class LogCategory( - internal val name: String, - internal val parent: LogCategory? = null, -) { - internal val path: List = if (parent == null) listOf(name) else parent.path + name - internal val pathAsString = path.joinToString(".") +public sealed interface LogCategory { + public val parent: LogCategory? - init { - categoriesByPath[name] = this - } + override fun toString(): String public companion object { + public val Realm: RealmLogCategory = RealmLogCategory - internal fun fromCoreValue(categoryPath: String): LogCategory = LogCategory.Realm //categoriesByPath[categoryPath]!! + internal fun fromCoreValue(categoryPath: String): LogCategory = + categoriesByPath[categoryPath]!! } } -public data object RealmLogCategory : LogCategory("Realm") { +public class LogCategoryImpl( + internal val name: String, + override val parent: LogCategory? = null, +) : LogCategory { + override fun toString(): String = if (parent != null) "$parent.$name" else name +} +public data object RealmLogCategory : LogCategory by newCategory("Realm") { /** * TODO */ @@ -82,7 +87,8 @@ public data object RealmLogCategory : LogCategory("Realm") { public val Sdk: LogCategory = SdkLogCategory } -public data object StorageLogCategory : LogCategory("Storage", RealmLogCategory) { +public data object StorageLogCategory : + LogCategory by newCategory("Storage", RealmLogCategory) { /** * TODO @@ -105,12 +111,20 @@ public data object StorageLogCategory : LogCategory("Storage", RealmLogCategory) public val Notification: LogCategory = NotificationLogCategory } -public data object TransactionLogCategory : LogCategory("Transaction", StorageLogCategory) -public data object QueryLogCategory : LogCategory("Query", StorageLogCategory) -public data object ObjectLogCategory : LogCategory("Object", StorageLogCategory) -public data object NotificationLogCategory : LogCategory("Notification", StorageLogCategory) +public data object TransactionLogCategory : + LogCategory by newCategory("Transaction", StorageLogCategory) -public data object SyncLogCategory : LogCategory("Sync", RealmLogCategory) { +public data object QueryLogCategory : + LogCategory by newCategory("Query", StorageLogCategory) + +public data object ObjectLogCategory : + LogCategory by newCategory("Object", StorageLogCategory) + +public data object NotificationLogCategory : + LogCategory by newCategory("Notification", StorageLogCategory) + +public data object SyncLogCategory : + LogCategory by newCategory("Sync", RealmLogCategory) { /** * TODO */ @@ -122,7 +136,8 @@ public data object SyncLogCategory : LogCategory("Sync", RealmLogCategory) { public val Server: LogCategory = ServerLogCategory } -public data object ClientLogCategory : LogCategory("Client", SyncLogCategory) { +public data object ClientLogCategory : + LogCategory by newCategory("Client", SyncLogCategory) { /** * TODO */ @@ -144,11 +159,20 @@ public data object ClientLogCategory : LogCategory("Client", SyncLogCategory) { public val Reset: LogCategory = ResetLogCategory } -public data object SessionLogCategory : LogCategory("Session", ClientLogCategory) -public data object ChangesetLogCategory : LogCategory("Changeset", ClientLogCategory) -public data object NetworkLogCategory : LogCategory("Network", ClientLogCategory) -public data object ResetLogCategory : LogCategory("Reset", ClientLogCategory) -public data object ServerLogCategory : LogCategory("Server", SyncLogCategory) +public data object SessionLogCategory : + LogCategory by newCategory("Session", ClientLogCategory) + +public data object ChangesetLogCategory : + LogCategory by newCategory("Changeset", ClientLogCategory) + +public data object NetworkLogCategory : + LogCategory by newCategory("Network", ClientLogCategory) + +public data object ResetLogCategory : + LogCategory by newCategory("Reset", ClientLogCategory) + +public data object ServerLogCategory : + LogCategory by newCategory("Server", SyncLogCategory) -public data object AppLogCategory : LogCategory("App", RealmLogCategory) -public data object SdkLogCategory : LogCategory("SDK", RealmLogCategory) +public data object AppLogCategory : LogCategory by newCategory("App", RealmLogCategory) +public data object SdkLogCategory : LogCategory by newCategory("SDK", RealmLogCategory) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt index 446b1b6c23..e02ae3fb2f 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt @@ -37,7 +37,7 @@ internal fun LogLevel.toCoreLogLevel(): CoreLogLevel { internal fun CoreLogLevel.fromCoreLogLevel(): LogLevel { return when (this) { - CoreLogLevel.RLM_LOG_LEVEL_ALL, + CoreLogLevel.RLM_LOG_LEVEL_ALL -> LogLevel.ALL CoreLogLevel.RLM_LOG_LEVEL_TRACE -> LogLevel.TRACE CoreLogLevel.RLM_LOG_LEVEL_DEBUG, CoreLogLevel.RLM_LOG_LEVEL_DETAIL -> LogLevel.DEBUG diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 03c22ecb65..42d1a74f73 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -53,20 +53,22 @@ public object RealmLog { /** * The current [LogLevel]. Changing this will affect all registered loggers. */ + public var level: LogLevel get() = getLevel(LogCategory.Realm) - set(value) = setLevel(value, LogCategory.Realm) - + set(value) { + setLevel(value, LogCategory.Realm) + } public fun setLevel(level: LogLevel, category: LogCategory = LogCategory.Realm) { - RealmInterop.realm_set_log_level_category(category.pathAsString, level.toCoreLogLevel()) + RealmInterop.realm_set_log_level_category(category.toString(), level.toCoreLogLevel()) } - public fun getLevel(category: LogCategory): LogLevel = - RealmInterop.realm_get_log_level_category(category.pathAsString).fromCoreLogLevel() - + public fun getLevel(category: LogCategory): LogLevel { + return RealmInterop.realm_get_log_level_category(category.toString()).fromCoreLogLevel() + } - init { + init { addDefaultSystemLogger() RealmInterop.realm_set_log_callback( level.toCoreLogLevel(), diff --git a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt index c825ca7382..5a5a668793 100644 --- a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt +++ b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt @@ -23,8 +23,4 @@ class TestLogger : RealmLogger { this.message = message this.args = args } - - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - TODO("Not yet implemented") - } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index 953318856f..17e4cf46bc 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -246,7 +246,7 @@ class RealmConfigurationTests { fun defaultLogLevel() { val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) .build() - assertEquals(LogLevel.INFO, config.log.level) + assertEquals(LogLevel.INFO, RealmLog.level) } @Test @@ -485,6 +485,8 @@ class RealmConfigurationTests { val expectedLogLevel = LogLevel.ALL RealmLog.level = expectedLogLevel + assertEquals(expectedLogLevel, RealmLog.level) + RealmConfiguration.Builder(setOf(Sample::class)) .build() diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 28545ec395..059b37cba5 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -371,7 +371,7 @@ class RealmLogTests { fun categoriesWatchdog() { val coreLogCategoryNames = RealmInterop.realm_get_category_names() - val logCategoriesPaths = logCategories.map { it.pathAsString } + val logCategoriesPaths = logCategories.map { "$it" } logCategoriesPaths.forEach { path -> assertContains(coreLogCategoryNames, path) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index 2398fa27bc..5bf65df413 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,8 +28,6 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils From 57682c9bab0329bc38dac6a8f78cd8d81b88cb49 Mon Sep 17 00:00:00 2001 From: Clemente Date: Fri, 15 Mar 2024 09:56:21 +0100 Subject: [PATCH 23/56] Restore default log level --- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 12 ++++++++++-- .../kotlin/test/common/RealmConfigurationTests.kt | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 42d1a74f73..2a23b30366 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -50,20 +50,28 @@ public object RealmLog { // copy this reference before using it. private var loggers: MutableList = mutableListOf() + // Log level that would be set by default + private val defaultLogLevel = LogLevel.WARN + /** * The current [LogLevel]. Changing this will affect all registered loggers. */ - public var level: LogLevel get() = getLevel(LogCategory.Realm) set(value) { setLevel(value, LogCategory.Realm) } + /** + * TODO + */ public fun setLevel(level: LogLevel, category: LogCategory = LogCategory.Realm) { RealmInterop.realm_set_log_level_category(category.toString(), level.toCoreLogLevel()) } + /** + * TODO + */ public fun getLevel(category: LogCategory): LogLevel { return RealmInterop.realm_get_log_level_category(category.toString()).fromCoreLogLevel() } @@ -71,7 +79,7 @@ public object RealmLog { init { addDefaultSystemLogger() RealmInterop.realm_set_log_callback( - level.toCoreLogLevel(), + defaultLogLevel.toCoreLogLevel(), // We set object : LogCallback { override fun log(categoryValue: String, logLevel: Short, message: String?) { // Create concatenated up front, since Core should already filter messages diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index 17e4cf46bc..0ac68096c8 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -246,7 +246,7 @@ class RealmConfigurationTests { fun defaultLogLevel() { val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) .build() - assertEquals(LogLevel.INFO, RealmLog.level) + assertEquals(LogLevel.WARN, RealmLog.level) } @Test From a708d6f7345e7822cb503e07c0528f0135160f66 Mon Sep 17 00:00:00 2001 From: Clemente Date: Fri, 15 Mar 2024 12:12:00 +0100 Subject: [PATCH 24/56] Add documentation --- .../kotlin/io/realm/kotlin/log/LogCategory.kt | 213 ++++++++++++++---- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 11 +- 2 files changed, 182 insertions(+), 42 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 67ca84598f..38330dd7da 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -13,36 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package io.realm.kotlin.log -/** - * Hierarchy - * Realm - * ├─► Storage - * │ ├─► Transaction - * │ ├─► Query - * │ ├─► Object - * │ └─► Notification - * ├─► Sync - * │ ├─► Client - * │ │ ├─► Session - * │ │ ├─► Changeset - * │ │ ├─► Network - * │ │ └─► Reset - * │ └─► Server - * ├─► App - * └─► Sdk +/* + * Core does not expose the different categories in compile time. + * + * This LogCategory design tries to overcome this issue by expressing the categories hierarchy + * in the kotlin type system, then validate it with a test watchdog. */ +// at package level as a workaround to ensure compatibility with darwin and jvm private val categoriesByPath: MutableMap = mutableMapOf() + internal fun newCategory( name: String, parent: LogCategory? = null, ): LogCategory = LogCategoryImpl(name, parent).also { category -> categoriesByPath["$category"] = category } + /** - * TODO + * Defines a log category for the Realm logger. */ public sealed interface LogCategory { public val parent: LogCategory? @@ -50,7 +42,28 @@ public sealed interface LogCategory { override fun toString(): String public companion object { - + /** + * Top level log category for Realm, updating this category level would set all other categories too. + * + * Category hierarchy: + * ``` + * Realm + * ├─► Storage + * │ ├─► Transaction + * │ ├─► Query + * │ ├─► Object + * │ └─► Notification + * ├─► Sync + * │ ├─► Client + * │ │ ├─► Session + * │ │ ├─► Changeset + * │ │ ├─► Network + * │ │ └─► Reset + * │ └─► Server + * ├─► App + * └─► Sdk + * ``` + */ public val Realm: RealmLogCategory = RealmLogCategory internal fun fromCoreValue(categoryPath: String): LogCategory = @@ -58,121 +71,241 @@ public sealed interface LogCategory { } } -public class LogCategoryImpl( +internal class LogCategoryImpl( internal val name: String, override val parent: LogCategory? = null, ) : LogCategory { override fun toString(): String = if (parent != null) "$parent.$name" else name } +/** + * Top level log category for Realm, updating this category level would set all other categories too. + * + * Category hierarchy: + * ``` + * Realm + * ├─► Storage + * │ ├─► Transaction + * │ ├─► Query + * │ ├─► Object + * │ └─► Notification + * ├─► Sync + * │ ├─► Client + * │ │ ├─► Session + * │ │ ├─► Changeset + * │ │ ├─► Network + * │ │ └─► Reset + * │ └─► Server + * ├─► App + * └─► Sdk + * ``` + */ public data object RealmLogCategory : LogCategory by newCategory("Realm") { /** - * TODO + * Log category for all storage related logs. + * + * Category hierarchy: + * ``` + * Storage + * ├─► Transaction + * ├─► Query + * ├─► Object + * └─► Notification + * ``` */ public val Storage: StorageLogCategory = StorageLogCategory /** - * TODO + * Log category for all sync related logs. + * + * Category hierarchy: + * ``` + * Sync + * ├─► Client + * │ ├─► Session + * │ ├─► Changeset + * │ ├─► Network + * │ └─► Reset + * └─► Server + * ``` */ public val Sync: SyncLogCategory = SyncLogCategory /** - * TODO + * Log category for all app related logs. */ public val App: LogCategory = AppLogCategory /** - * TODO + * Log category for all sdk related logs. */ public val Sdk: LogCategory = SdkLogCategory } -public data object StorageLogCategory : - LogCategory by newCategory("Storage", RealmLogCategory) { +/** + * Log category for all storage related logs. + * + * Category hierarchy: + * ``` + * Storage + * ├─► Transaction + * ├─► Query + * ├─► Object + * └─► Notification + * ``` + */ +public data object StorageLogCategory : LogCategory by newCategory("Storage", RealmLogCategory) { /** - * TODO + * Log category for all transaction related logs. */ public val Transaction: LogCategory = TransactionLogCategory /** - * TODO + * Log category for all query related logs. */ public val Query: LogCategory = QueryLogCategory /** - * TODO + * Log category for all object related logs. */ public val Object: LogCategory = ObjectLogCategory /** - * TODO + * Log category for all notification related logs. */ public val Notification: LogCategory = NotificationLogCategory } +/** + * Log category for all transaction related logs. + */ public data object TransactionLogCategory : LogCategory by newCategory("Transaction", StorageLogCategory) -public data object QueryLogCategory : - LogCategory by newCategory("Query", StorageLogCategory) +/** + * Log category for all query related logs. + */ +public data object QueryLogCategory : LogCategory by newCategory("Query", StorageLogCategory) -public data object ObjectLogCategory : - LogCategory by newCategory("Object", StorageLogCategory) +/** + * Log category for all object related logs. + */ +public data object ObjectLogCategory : LogCategory by newCategory("Object", StorageLogCategory) +/** + * Log category for all notification related logs. + */ public data object NotificationLogCategory : LogCategory by newCategory("Notification", StorageLogCategory) +/** + * Category hierarchy: + * ``` + * Sync + * ├─► Client + * │ ├─► Session + * │ ├─► Changeset + * │ ├─► Network + * │ └─► Reset + * └─► Server + * ``` + */ public data object SyncLogCategory : LogCategory by newCategory("Sync", RealmLogCategory) { /** - * TODO + * Log category for all sync client related logs. + * + * Category hierarchy: + * ``` + * Client + * ├─► Session + * ├─► Changeset + * ├─► Network + * └─► Reset + * ``` */ public val Client: ClientLogCategory = ClientLogCategory /** - * TODO + * Log category for all sync server related logs. */ public val Server: LogCategory = ServerLogCategory } +/** + * + * Log category for all sync client related logs. + * + * Category hierarchy: + * ``` + * Client + * ├─► Session + * ├─► Changeset + * ├─► Network + * └─► Reset + * ``` + */ public data object ClientLogCategory : LogCategory by newCategory("Client", SyncLogCategory) { + /** - * TODO + * Log category for all sync session related logs. */ public val Session: LogCategory = SessionLogCategory /** - * TODO + * Log category for all sync changesets related logs. */ public val Changeset: LogCategory = ChangesetLogCategory /** - * TODO + * Log category for all sync network logs. */ public val Network: LogCategory = NetworkLogCategory /** - * TODO + * Log category for all sync reset related logs. */ public val Reset: LogCategory = ResetLogCategory } +/** + * Log category for all sync session related logs. + */ public data object SessionLogCategory : LogCategory by newCategory("Session", ClientLogCategory) +/** + * Log category for all sync changesets related logs. + */ public data object ChangesetLogCategory : LogCategory by newCategory("Changeset", ClientLogCategory) +/** + * Log category for all sync network logs. + */ public data object NetworkLogCategory : LogCategory by newCategory("Network", ClientLogCategory) +/** + * Log category for all sync reset related logs. + */ public data object ResetLogCategory : LogCategory by newCategory("Reset", ClientLogCategory) +/** + * Log category for all sync server related logs. + */ public data object ServerLogCategory : LogCategory by newCategory("Server", SyncLogCategory) +/** + * Log category for all app related logs. + */ public data object AppLogCategory : LogCategory by newCategory("App", RealmLogCategory) + +/** + * Log category for all sdk related logs. + */ public data object SdkLogCategory : LogCategory by newCategory("SDK", RealmLogCategory) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 2a23b30366..aae011f7ba 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -63,14 +63,21 @@ public object RealmLog { } /** - * TODO + * Sets the log level of a log category. By setting the log level of a category all its subcategories + * would also be updated to match its level. + * + * @param level target log level. + * @param category target log category, [LogCategory.Realm] by default. */ public fun setLevel(level: LogLevel, category: LogCategory = LogCategory.Realm) { RealmInterop.realm_set_log_level_category(category.toString(), level.toCoreLogLevel()) } /** - * TODO + * Gets the current log level of a log category. + * + * @param category target log category. + * @return current [category] log level. */ public fun getLevel(category: LogCategory): LogLevel { return RealmInterop.realm_get_log_level_category(category.toString()).fromCoreLogLevel() From 7739e2a67e5c405f4b9b5844b06be59dfe0f3140 Mon Sep 17 00:00:00 2001 From: Clemente Date: Fri, 15 Mar 2024 12:52:20 +0100 Subject: [PATCH 25/56] Contains support Deprecated method validation Changelog --- CHANGELOG.md | 1 + .../kotlin/io/realm/kotlin/log/LogCategory.kt | 3 + .../realm/kotlin/test/common/RealmLogTests.kt | 57 +++++++++++++++++++ .../mongodb/common/AppConfigurationTests.kt | 2 + 4 files changed, 63 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 322e07202f..541b95a085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Index on list of strings property now supported (Core issue [realm/realm-core#7142](https://github.com/realm/realm-core/pull/7142)) * Improved performance of RQL (parsed) queries on a non-linked string property using: >, >=, <, <=, operators and fixed behaviour that a null string should be evaulated as less than everything, previously nulls were not matched. (Core issue [realm/realm-core#3939](https://github.com/realm/realm-core/issues/3939). * Updated bundled OpenSSL version to 3.2.0 (Core issue [realm/realm-core#7303](https://github.com/realm/realm-core/pull/7303)) +* Add support for filtering logs by category. (Issue [#1691](https://github.com/realm/realm-kotlin/issues/1691) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1038)) ### Fixed * `@count`/`@size` is now supported for `RealmAny` properties (Core issue [realm/realm-core#7280](https://github.com/realm/realm-core/issues/7280), since v10.0.0) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 38330dd7da..aa1470b14f 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -39,6 +39,7 @@ internal fun newCategory( public sealed interface LogCategory { public val parent: LogCategory? + public operator fun contains(element: LogCategory): Boolean override fun toString(): String public companion object { @@ -75,6 +76,8 @@ internal class LogCategoryImpl( internal val name: String, override val parent: LogCategory? = null, ) : LogCategory { + override fun contains(element: LogCategory): Boolean = "$element".contains("$this") + override fun toString(): String = if (parent != null) "$parent.$name" else name } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 059b37cba5..f703d6ace1 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -237,6 +237,46 @@ class RealmLogTests { } } + @Test + fun deprecatedMethodWork1() { + val called = atomic(false) + val customLogger = object : RealmLogger { + override val level: LogLevel = LogLevel.ALL + override val tag: String = "CUSTOM" + override fun log( + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any? + ) { + assertEquals("Hello", message) + called.value = true + } + } + RealmLog.add(customLogger) + RealmLog.trace("Hello") + assertTrue(called.value) + } + + @Test + fun deprecatedMethodWork2() { + val called = atomic(false) + val customLogger = object : RealmLogger { + override val level: LogLevel = LogLevel.ALL + override val tag: String = "CUSTOM" + override fun log( + level: LogLevel, + message: String + ) { + assertEquals("Hello", message) + called.value = true + } + } + RealmLog.add(customLogger) + RealmLog.trace("Hello") + assertTrue(called.value) + } + @Test fun addLogger() { val called = atomic(false) @@ -244,11 +284,13 @@ class RealmLogTests { override val level: LogLevel = LogLevel.ALL override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any? ) { + assertEquals(LogCategory.Realm.Sdk, category) assertEquals("Hello", message) called.value = true } @@ -265,11 +307,13 @@ class RealmLogTests { override val level: LogLevel = LogLevel.ALL override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any? ) { + assertEquals(LogCategory.Realm.Sdk, category) assertEquals("Hello", message) called.incrementAndGet() } @@ -287,11 +331,13 @@ class RealmLogTests { override val level: LogLevel = LogLevel.ALL override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any? ) { + assertEquals(LogCategory.Realm.Sdk, category) assertEquals("Hello", message) called.incrementAndGet() } @@ -308,6 +354,7 @@ class RealmLogTests { override val level: LogLevel = LogLevel.ALL override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, @@ -325,6 +372,7 @@ class RealmLogTests { override val level: LogLevel = LogLevel.ALL override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, @@ -367,6 +415,15 @@ class RealmLogTests { } } + @Test + fun categoryContains() { + assertFalse(LogCategory.Realm in LogCategory.Realm.Storage) + + assertTrue(LogCategory.Realm.Storage in LogCategory.Realm) + assertTrue(LogCategory.Realm.Storage.Transaction in LogCategory.Realm) + assertTrue(LogCategory.Realm.Storage.Transaction in LogCategory.Realm.Storage) + } + @Test fun categoriesWatchdog() { val coreLogCategoryNames = RealmInterop.realm_get_category_names() diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt index af8475f50c..6cc0396ec0 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt @@ -21,6 +21,7 @@ import io.realm.kotlin.internal.platform.appFilesDirectory import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger @@ -406,6 +407,7 @@ class AppConfigurationTests { override val tag: String = "LOGGER" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, From 76b51bbfc931885c52bba80cc11b120661e7d549 Mon Sep 17 00:00:00 2001 From: Clemente Date: Fri, 15 Mar 2024 14:27:34 +0100 Subject: [PATCH 26/56] Fix expression did not evaluate to a constant compile error in windows --- packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp index 7ce3eb9fa5..cf17f826b6 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp @@ -1375,9 +1375,10 @@ realm_class_info_t_cleanup(realm_class_info_t * value) { jobjectArray realm_get_log_category_names() { JNIEnv* env = get_env(true); - size_t bufferSize = 50; - const char* category_names[bufferSize]; - size_t namesCount = realm_get_category_names(bufferSize, category_names); + size_t namesCount = realm_get_category_names(0, nullptr); + + const char** category_names = new const char*[namesCount]; + realm_get_category_names(namesCount, category_names); auto array = env->NewObjectArray(namesCount, JavaClassGlobalDef::java_lang_string(), nullptr); From 121597e3a47937c800bf472b88c543ac732ca4cb Mon Sep 17 00:00:00 2001 From: Clemente Date: Fri, 15 Mar 2024 14:55:55 +0100 Subject: [PATCH 27/56] Clean up --- packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp index cf17f826b6..cdb3df8767 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp @@ -1387,5 +1387,7 @@ jobjectArray realm_get_log_category_names() { env->SetObjectArrayElement(array, i, string); } + delete[] category_names; + return array; } From 63378e9a0b07b4dfdb361c11cdcb062217596cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Mon, 18 Mar 2024 10:35:22 +0100 Subject: [PATCH 28/56] Read core version from dependencies.yml --- packages/gradle-plugin/build.gradle.kts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/gradle-plugin/build.gradle.kts b/packages/gradle-plugin/build.gradle.kts index 09ac559bbd..673c3ab092 100644 --- a/packages/gradle-plugin/build.gradle.kts +++ b/packages/gradle-plugin/build.gradle.kts @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import kotlin.text.toBoolean +import org.yaml.snakeyaml.Yaml +import java.io.FileInputStream plugins { kotlin("jvm") @@ -22,6 +23,12 @@ plugins { id("realm-publisher") } +buildscript { + dependencies { + classpath("org.yaml:snakeyaml:1.33") + } +} + dependencies { compileOnly(kotlin("gradle-plugin")) compileOnly("com.android.tools.build:gradle:${Versions.Android.buildTools}") @@ -96,16 +103,16 @@ sourceSets { // Task to generate gradle plugin runtime constants for SDK and core versions tasks.create("versionConstants") { val coreDependenciesFile = layout.projectDirectory.file( - listOf("..", "external", "core", "dependencies.list").joinToString(File.separator) + listOf("..", "external", "core", "dependencies.yml").joinToString(File.separator) ) - val outputDir = file(versionDirectory) - inputs.property("version", project.version) inputs.file(coreDependenciesFile) + inputs.property("version", project.version) + val outputDir = file(versionDirectory) outputs.dir(outputDir) - val versionRegex = "^VERSION=(.*)\$".toRegex() - val coreVersion = providers.fileContents(coreDependenciesFile).asText.get().lineSequence() - .map { dependecy -> versionRegex.find(dependecy)?.groups?.get(1)?.value }.single { it != null } + val yaml = Yaml() + val coreDependencies: Map = yaml.load(FileInputStream(coreDependenciesFile.asFile)) + val coreVersion = coreDependencies["VERSION"] doLast { val versionFile = file("$outputDir/io/realm/kotlin/gradle/version.kt") From 8910455ac7655bf7bdf8bd9a5b2fd37e8e1a1f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Tue, 19 Mar 2024 09:58:41 +0100 Subject: [PATCH 29/56] Apply suggestions from code review Co-authored-by: Nabil Hachicha --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 322e07202f..288601250d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from file format v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. ### Breaking changes -* If you want to query using @type operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types. +* If you want to query using `@type` operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types. * Binary data and String data are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a RealmAny property, as now only strings will be returned. If searching for Binary data is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. (Core issue [realm/realm-core#6407](https://github.com/realm/realm-core/issues/6407)). * Sorting order of strings has changed to use standard unicode codepoint order instead of grouping similar english letters together. A noticeable change will be from "aAbBzZ" to "ABZabz". (Core issue [realm/realm-core#2573](https://github.com/realm/realm-core/issues/2573)) From 7bbcf894bb7888a2ed1aed17469c024087d7e49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Tue, 19 Mar 2024 10:00:14 +0100 Subject: [PATCH 30/56] Updates according to review comments --- .github/workflows/pr.yml | 6 +++--- CHANGELOG.md | 2 -- buildSrc/src/main/kotlin/Config.kt | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ccbbcfd08c..29363a34ba 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -575,15 +575,15 @@ jobs: - name: Build Android Base Test Apk working-directory: packages - run: ./gradlew :test-base:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info + run: ./gradlew :test-base:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false - name: Build Android Sync Test Apk working-directory: packages - run: ./gradlew :test-sync:packageDebug :test-sync:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info + run: ./gradlew :test-sync:packageDebug :test-sync:assembleAndroidTest -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false - name: Build packages working-directory: packages - run: ./gradlew publishCIPackages -Prealm.kotlin.targets=android -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false --info + run: ./gradlew publishCIPackages -Prealm.kotlin.targets=android -Prealm.kotlin.buildRealmCore=false -Prealm.kotlin.mainHost=false - name: Store build cache uses: actions/cache@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 288601250d..3a108d8636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,8 +49,6 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi ## 1.14.0 (2024-03-08) -This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from fileformat v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. - ### Breaking Changes * None. diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index b6631f5b29..6be38cee34 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -138,6 +138,7 @@ object Versions { const val relinker = "1.4.5" // https://github.com/KeepSafe/ReLinker const val serialization = "1.6.0" // https://kotlinlang.org/docs/releases.html#release-details const val shadowJar = "6.1.0" // https://mvnrepository.com/artifact/com.github.johnrengelman.shadow/com.github.johnrengelman.shadow.gradle.plugin?repo=gradle-plugins + const val snakeYaml = "1.33" // https://github.com/snakeyaml/snakeyaml val sourceCompatibilityVersion = JavaVersion.VERSION_1_8 // Language level of any Java source code. val targetCompatibilityVersion = JavaVersion.VERSION_1_8 // Version of generated JVM bytecode from Java files. } From 1dfc39b24739944eec03e6554c5a2b932634e8a1 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 21 Mar 2024 15:06:07 +0100 Subject: [PATCH 31/56] Bump core --- .../kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt | 2 +- .../kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt | 4 ++-- .../kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt | 3 +-- packages/external/core | 2 +- packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp | 4 +--- packages/jni-swig-stub/src/main/jni/realm_api_helpers.h | 2 +- .../src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt | 2 +- 7 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 83cc9d28f2..271df9b962 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -579,7 +579,7 @@ expect object RealmInterop { fun realm_sync_client_config_set_multiplex_sessions(syncClientConfig: RealmSyncClientConfigurationPointer, enabled: Boolean) - fun realm_set_log_callback(level: CoreLogLevel, callback: LogCallback) + fun realm_set_log_callback(callback: LogCallback) fun realm_set_log_level(level: CoreLogLevel) diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 0bf6ec6757..48e5b4c33b 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -1287,8 +1287,8 @@ actual object RealmInterop { realmc.realm_sync_client_config_set_multiplex_sessions(syncClientConfig.cptr(), enabled) } - actual fun realm_set_log_callback(level: CoreLogLevel, callback: LogCallback) { - realmc.set_log_callback(level.priority, callback) + actual fun realm_set_log_callback(callback: LogCallback) { + realmc.set_log_callback(callback) } actual fun realm_set_log_level(level: CoreLogLevel) { diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index ad6a9a41cb..d4f873753f 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -2420,13 +2420,12 @@ actual object RealmInterop { realm_wrapper.realm_sync_client_config_set_multiplex_sessions(syncClientConfig.cptr(), enabled) } - actual fun realm_set_log_callback(level: CoreLogLevel, callback: LogCallback) { + actual fun realm_set_log_callback(callback: LogCallback) { realm_wrapper.realm_set_log_callback( staticCFunction { userData, category, logLevel, message -> val userDataLogCallback = safeUserData(userData) userDataLogCallback.log(category!!.toKString(), logLevel.toShort(), message?.toKString()) }, - level.priority.toUInt(), StableRef.create(callback).asCPointer(), staticCFunction { userData -> disposeUserData<() -> LogCallback>(userData) } ) diff --git a/packages/external/core b/packages/external/core index 6491844109..8084ba9d75 160000 --- a/packages/external/core +++ b/packages/external/core @@ -1 +1 @@ -Subproject commit 6491844109bd299e82520f54d70101cb6a8fbae3 +Subproject commit 8084ba9d75776d42684a3562fe8b962ea8838176 diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp index cdb3df8767..5374e2fb90 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp @@ -959,9 +959,8 @@ realm_sync_socket_t* realm_sync_websocket_new(int64_t sync_client_config_ptr, jo // *** END - WebSocket Client (Platform Networking) *** // -void set_log_callback(jint j_log_level, jobject log_callback) { +void set_log_callback(jobject log_callback) { auto jenv = get_env(false); -auto log_level = static_cast(j_log_level); realm_set_log_callback([](void *userdata, const char *category, realm_log_level_e level, const char *message) { auto log_callback = static_cast(userdata); auto jenv = get_env(true); @@ -978,7 +977,6 @@ realm_set_log_callback([](void *userdata, const char *category, realm_log_level_ jni_check_exception(jenv); jenv->PopLocalFrame(NULL); }, - log_level, jenv->NewGlobalRef(log_callback), // userdata is the log callback [](void* userdata) { // The log callback is a static global method that is intended to diff --git a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h index 37d1347d68..adcd624d1c 100644 --- a/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h +++ b/packages/jni-swig-stub/src/main/jni/realm_api_helpers.h @@ -51,7 +51,7 @@ realm_http_transport_t* realm_network_transport_new(jobject network_transport); void -set_log_callback(jint log_level, jobject log_callback); +set_log_callback(jobject log_callback); realm_scheduler_t* realm_create_scheduler(jobject dispatchScheduler); diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index aae011f7ba..d97e35342a 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -85,8 +85,8 @@ public object RealmLog { init { addDefaultSystemLogger() + setLevel(level = defaultLogLevel) // Set the log level to the SDKs (might be different from cores default INFO) RealmInterop.realm_set_log_callback( - defaultLogLevel.toCoreLogLevel(), // We set object : LogCallback { override fun log(categoryValue: String, logLevel: Short, message: String?) { // Create concatenated up front, since Core should already filter messages From 93ec563e97ecec8c0d9baddf42c8cf1d56ed6ab3 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 21 Mar 2024 15:18:41 +0100 Subject: [PATCH 32/56] cleanup --- .../kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index d4f873753f..f896b546fd 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -2442,7 +2442,6 @@ actual object RealmInterop { actual fun realm_get_log_level_category(category: String): CoreLogLevel = CoreLogLevel.valueFromPriority(realm_wrapper.realm_get_log_level_category(category).toShort()) -// public external expect fun realm_get_category_names(num_values: platform.posix.size_t /* = kotlin.ULong */, out_values: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } actual fun realm_get_category_names(): List { memScoped { val namesCount = realm_wrapper.realm_get_category_names(0u, null) From c6384fa1ea92c51179ffcfc5316b3ed1995974df Mon Sep 17 00:00:00 2001 From: Clemente Date: Mon, 6 May 2024 12:23:00 +0200 Subject: [PATCH 33/56] Fix changelog merge issue --- CHANGELOG.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ffa7026dc..b9ea6a516b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -122,12 +122,6 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Minimum Android Gradle Plugin version: 4.1.3. * Minimum Android SDK: 16. * Minimum R8: 8.0.34. -<<<<<<< HEAD - -### Internal -* Updated to Realm Core 14.2.0 commit 383bdc81e36293b22868ee085a6f5c265115556d. -* Deprecated Jenkins and switching to Github Action ([JIRA]https://jira.mongodb.org/browse/RKOTLIN-825). -======= ### Internal * Updated to Realm Core 14.5.1 commit 316889b967f845fbc10b4422f96c7eadd47136f2. @@ -166,7 +160,6 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi ### Internal - Deprecated Jenkins and switching to Github Action ([JIRA]https://jira.mongodb.org/browse/RKOTLIN-825). ->>>>>>> main ## 1.14.0 (2024-03-08) From 1cbecdc24b71396b51a3674d2dd0504de51d9bea Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 15:45:29 +0200 Subject: [PATCH 34/56] defaults --- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index e968d525e0..8a337b6487 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -95,10 +95,10 @@ public object RealmLog { val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() doLog( - category, level, null, - if (message.isNullOrBlank()) { null } else { "[Core] $message" } + if (message.isNullOrBlank()) { null } else { "[Core] $message" }, + category, ) } } @@ -180,7 +180,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun trace(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, throwable, null) + doLog(LogLevel.TRACE, throwable, null) } /** @@ -192,7 +192,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, throwable, message, *args) + doLog(LogLevel.TRACE, throwable, message, *args) } /** @@ -203,7 +203,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.TRACE, null, message, *args) + doLog(LogLevel.TRACE, null, message, *args) } /** @@ -212,7 +212,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun debug(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable, null) + doLog(LogLevel.DEBUG, throwable, null) } /** @@ -224,7 +224,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable, message, *args) + doLog(LogLevel.DEBUG, throwable, message, *args) } /** @@ -235,7 +235,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.DEBUG, null, message, *args) + doLog(LogLevel.DEBUG, null, message, *args) } /** @@ -244,7 +244,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun info(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.INFO, throwable, null) + doLog(LogLevel.INFO, throwable, null) } /** @@ -256,7 +256,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.INFO, throwable, message, *args) + doLog(LogLevel.INFO, throwable, message, *args) } /** @@ -267,7 +267,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.INFO, null, message, *args) + doLog(LogLevel.INFO, null, message, *args) } /** @@ -276,7 +276,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun warn(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WARN, throwable, null) + doLog(LogLevel.WARN, throwable, null) } /** @@ -288,7 +288,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WARN, throwable, message, *args) + doLog(LogLevel.WARN, throwable, message, *args) } /** @@ -299,7 +299,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WARN, null, message, *args) + doLog(LogLevel.WARN, null, message, *args) } /** @@ -308,7 +308,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun error(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, throwable, null) + doLog(LogLevel.ERROR, throwable, null) } /** @@ -320,7 +320,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, throwable, message, *args) + doLog(LogLevel.ERROR, throwable, message, *args) } /** @@ -331,7 +331,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.ERROR, null, message, *args) + doLog(LogLevel.ERROR, null, message, *args) } /** @@ -340,7 +340,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun wtf(throwable: Throwable?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WTF, throwable, null) + doLog(LogLevel.WTF, throwable, null) } /** @@ -352,7 +352,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WTF, throwable, message, *args) + doLog(LogLevel.WTF, throwable, message, *args) } /** @@ -363,13 +363,28 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(message: String, vararg args: Any?) { - doLog(LogCategory.Realm.Sdk, LogLevel.WTF, null, message, *args) + doLog(LogLevel.WTF, null, message, *args) } + internal inline fun doLog( + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) = doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) + + internal fun doLog( + level: LogLevel, + throwable: Throwable?, + message: () -> String?, + vararg args: Any?, + ) = doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) + + /** * Log a message. */ - internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?, ) { if (level.priority >= this.level.priority) { // Copy the reference to loggers so they are stable while iterating them. val loggers = this.loggers From 6d3c84d89c13735657ec652a2228c2f2dab845a7 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 17:02:16 +0200 Subject: [PATCH 35/56] Update test --- .../io/realm/kotlin/test/common/RealmConfigurationTests.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index 0ac68096c8..002ce4719a 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -246,6 +246,7 @@ class RealmConfigurationTests { fun defaultLogLevel() { val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) .build() + assertEquals(LogLevel.WARN, config.log.level) assertEquals(LogLevel.WARN, RealmLog.level) } From e434e904a321c61805511dd5506cfcc004855b62 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 17:32:44 +0200 Subject: [PATCH 36/56] Add category to log output. --- .../src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 8a337b6487..c6796502f7 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -97,7 +97,7 @@ public object RealmLog { doLog( level, null, - if (message.isNullOrBlank()) { null } else { "[Core] $message" }, + if (message.isNullOrBlank()) { null } else { "[$category] $message" }, category, ) } From 86f48ed7fb2a1ce168025c14c01726dcff929b7d Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 17:53:19 +0200 Subject: [PATCH 37/56] Fix cycle in Logger.log --- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 13 +++---- .../realm/kotlin/test/common/RealmLogTests.kt | 37 +++++++++++++++++++ .../io/realm/kotlin/test/common/RealmTests.kt | 3 ++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index bdeb98f212..886467b5e9 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -40,22 +40,19 @@ public interface RealmLogger { * Log an event. */ public fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - log(level, throwable, message, *args) + log(level, message!!) + log(level, null, message) } /** * Log an event. */ @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) - public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - log(level, message!!) - } + public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) {} /** * Log an event. */ @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) - public fun log(level: LogLevel, message: String) { - log(LogCategory.Realm.Sdk, level, null, message) - } -} + public fun log(level: LogLevel, message: String) {} +} \ No newline at end of file diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index f703d6ace1..c83303c6b8 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -386,6 +386,43 @@ class RealmLogTests { RealmLog.trace("Hello") // Should not hit `fail()` } + @Test + fun addDeprecatedLogger_1() { + val called = atomic(false) + val customLogger = object : RealmLogger { + override val level: LogLevel = LogLevel.ALL + override val tag: String = "CUSTOM" + override fun log( + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { + assertEquals("Hello", message) + called.value = true + } + } + RealmLog.add(customLogger) + RealmLog.trace("Hello") + assertTrue(called.value) + } + + @Test + fun addDeprecatedLogger_2() { + val called = atomic(false) + val customLogger = object : RealmLogger { + override val level: LogLevel = LogLevel.ALL + override val tag: String = "CUSTOM" + override fun log(level: LogLevel, message: String) { + assertEquals("Hello", message) + called.value = true + } + } + RealmLog.add(customLogger) + RealmLog.trace("Hello") + assertTrue(called.value) + } + @Test fun removeAll_falseIfNoLoggerWereRemoved() { assertTrue(RealmLog.removeAll()) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index 5bf65df413..bd888eecf0 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,6 +28,8 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf +import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils @@ -72,6 +74,7 @@ class RealmTests { @BeforeTest fun setup() { + RealmLog.level = LogLevel.ALL tmpDir = PlatformUtils.createTempDir() configuration = RealmConfiguration.Builder(setOf(Parent::class, Child::class)) .directory(tmpDir) From b935051fff8bef47687dcb5057beeb6b9d809999 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 18:02:09 +0200 Subject: [PATCH 38/56] Clean up --- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 10 +------ .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index c6796502f7..ade4c2e642 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -373,18 +373,10 @@ public object RealmLog { vararg args: Any?, ) = doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) - internal fun doLog( - level: LogLevel, - throwable: Throwable?, - message: () -> String?, - vararg args: Any?, - ) = doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) - - /** * Log a message. */ - internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?, ) { + internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { if (level.priority >= this.level.priority) { // Copy the reference to loggers so they are stable while iterating them. val loggers = this.loggers diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index 886467b5e9..3728b734f6 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -39,7 +39,13 @@ public interface RealmLogger { /** * Log an event. */ - public fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + public fun log( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { log(level, message!!) log(level, null, message) } @@ -47,12 +53,20 @@ public interface RealmLogger { /** * Log an event. */ - @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) - public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) {} + @Deprecated( + "Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", + ReplaceWith("log") + ) + public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + } /** * Log an event. */ - @Deprecated("Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", ReplaceWith("log")) - public fun log(level: LogLevel, message: String) {} -} \ No newline at end of file + @Deprecated( + "Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", + ReplaceWith("log") + ) + public fun log(level: LogLevel, message: String) { + } +} From b31baba2eff7e55a8e3d5551d7d3bec512da2fc7 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 9 May 2024 18:28:01 +0200 Subject: [PATCH 39/56] Add test to show SDK logs are not filtered out --- .../realm/kotlin/test/common/RealmLogTests.kt | 28 +++++++++++++++++++ .../io/realm/kotlin/test/common/RealmTests.kt | 3 -- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index c83303c6b8..446e0362c6 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -16,6 +16,7 @@ @file:Suppress("invisible_reference", "invisible_member") package io.realm.kotlin.test.common +import io.realm.kotlin.internal.ContextLogger import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel @@ -26,6 +27,7 @@ import io.realm.kotlin.test.util.Utils import kotlinx.atomicfu.atomic import kotlin.test.AfterTest import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertContains import kotlin.test.assertEquals @@ -475,4 +477,30 @@ class RealmLogTests { assertContains(logCategoriesPaths, path) } } + + @Test + @Ignore // https://jira.mongodb.org/browse/RKOTLIN-1076 + fun filterSdkLogs() { + val called = atomic(false) + val customLogger = object : RealmLogger { + override val level: LogLevel = LogLevel.ALL + override val tag: String = "CUSTOM" + override fun log( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { + called.value = true + } + } + RealmLog.add(customLogger) + + ContextLogger("Sdk").run { + RealmLog.setLevel(LogLevel.NONE, LogCategory.Realm.Sdk) + warn("should be filtered") + assertFalse(called.value, "Unexpected message logged") + } + } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index bd888eecf0..5bf65df413 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,8 +28,6 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils @@ -74,7 +72,6 @@ class RealmTests { @BeforeTest fun setup() { - RealmLog.level = LogLevel.ALL tmpDir = PlatformUtils.createTempDir() configuration = RealmConfiguration.Builder(setOf(Parent::class, Child::class)) .directory(tmpDir) From 9442e7359ef62f34865221cfa48ce016cf9fb8f5 Mon Sep 17 00:00:00 2001 From: Clemente Date: Mon, 13 May 2024 15:56:18 +0200 Subject: [PATCH 40/56] refactor interface --- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index 3728b734f6..9f5a24f252 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -46,8 +46,7 @@ public interface RealmLogger { message: String?, vararg args: Any?, ) { - log(level, message!!) - log(level, null, message) + log(level, throwable, message, *args) } /** @@ -58,6 +57,7 @@ public interface RealmLogger { ReplaceWith("log") ) public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + TODO("log() shouldn't be called. Overwrite the category-variant instead") } /** @@ -68,5 +68,11 @@ public interface RealmLogger { ReplaceWith("log") ) public fun log(level: LogLevel, message: String) { + log( + category = LogCategory.Realm.Sdk, + level = level, + throwable = null, + message = message + ) } } From a6863cd1eb06b4eaa1bcb2d0f471596b435527d2 Mon Sep 17 00:00:00 2001 From: Clemente Date: Tue, 14 May 2024 15:57:34 +0200 Subject: [PATCH 41/56] filter sdk messages --- .../io/realm/kotlin/internal/ContextLogger.kt | 12 ++- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 77 ++++++++----------- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt index dc92aac7af..82e3ba4e0a 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt @@ -3,6 +3,7 @@ package io.realm.kotlin.internal import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog +import io.realm.kotlin.log.SdkLogCategory /** * Internal logger class used to inject context aware information into log message @@ -85,7 +86,14 @@ public class ContextLogger(public val context: String? = null) { RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, null) } - private inline fun doLog(level: LogLevel, throwable: Throwable?, message: () -> String?, vararg args: Any?) { - RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) + private inline fun doLog( + level: LogLevel, + throwable: Throwable?, + message: () -> String?, + vararg args: Any?, + ) { + if (level >= RealmLog.getLevel(SdkLogCategory)) { + RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, message(), *args) + } } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index ade4c2e642..3a77c4bbe8 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -95,10 +95,10 @@ public object RealmLog { val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() doLog( + category, level, null, if (message.isNullOrBlank()) { null } else { "[$category] $message" }, - category, ) } } @@ -180,7 +180,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun trace(throwable: Throwable?) { - doLog(LogLevel.TRACE, throwable, null) + sdkLog(LogLevel.TRACE, throwable, null) } /** @@ -192,7 +192,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.TRACE, throwable, message, *args) + sdkLog(LogLevel.TRACE, throwable, message, *args) } /** @@ -203,7 +203,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun trace(message: String, vararg args: Any?) { - doLog(LogLevel.TRACE, null, message, *args) + sdkLog(LogLevel.TRACE, null, message, *args) } /** @@ -212,7 +212,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun debug(throwable: Throwable?) { - doLog(LogLevel.DEBUG, throwable, null) + sdkLog(LogLevel.DEBUG, throwable, null) } /** @@ -224,7 +224,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.DEBUG, throwable, message, *args) + sdkLog(LogLevel.DEBUG, throwable, message, *args) } /** @@ -235,7 +235,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun debug(message: String, vararg args: Any?) { - doLog(LogLevel.DEBUG, null, message, *args) + sdkLog(LogLevel.DEBUG, null, message, *args) } /** @@ -244,7 +244,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun info(throwable: Throwable?) { - doLog(LogLevel.INFO, throwable, null) + sdkLog(LogLevel.INFO, throwable, null) } /** @@ -256,7 +256,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.INFO, throwable, message, *args) + sdkLog(LogLevel.INFO, throwable, message, *args) } /** @@ -267,7 +267,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun info(message: String, vararg args: Any?) { - doLog(LogLevel.INFO, null, message, *args) + sdkLog(LogLevel.INFO, null, message, *args) } /** @@ -276,7 +276,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun warn(throwable: Throwable?) { - doLog(LogLevel.WARN, throwable, null) + sdkLog(LogLevel.WARN, throwable, null) } /** @@ -288,7 +288,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.WARN, throwable, message, *args) + sdkLog(LogLevel.WARN, throwable, message, *args) } /** @@ -299,7 +299,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun warn(message: String, vararg args: Any?) { - doLog(LogLevel.WARN, null, message, *args) + sdkLog(LogLevel.WARN, null, message, *args) } /** @@ -308,7 +308,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun error(throwable: Throwable?) { - doLog(LogLevel.ERROR, throwable, null) + sdkLog(LogLevel.ERROR, throwable, null) } /** @@ -320,7 +320,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.ERROR, throwable, message, *args) + sdkLog(LogLevel.ERROR, throwable, message, *args) } /** @@ -331,7 +331,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun error(message: String, vararg args: Any?) { - doLog(LogLevel.ERROR, null, message, *args) + sdkLog(LogLevel.ERROR, null, message, *args) } /** @@ -340,7 +340,7 @@ public object RealmLog { * @param throwable optional exception to log. */ internal fun wtf(throwable: Throwable?) { - doLog(LogLevel.WTF, throwable, null) + sdkLog(LogLevel.WTF, throwable, null) } /** @@ -352,7 +352,7 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(throwable: Throwable?, message: String, vararg args: Any?) { - doLog(LogLevel.WTF, throwable, message, *args) + sdkLog(LogLevel.WTF, throwable, message, *args) } /** @@ -363,42 +363,31 @@ public object RealmLog { * options. Only `%s`, `%d` and `%f` are supported. */ internal fun wtf(message: String, vararg args: Any?) { - doLog(LogLevel.WTF, null, message, *args) + sdkLog(LogLevel.WTF, null, message, *args) } - internal inline fun doLog( + private inline fun sdkLog( level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?, - ) = doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) - - /** - * Log a message. - */ - internal fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - if (level.priority >= this.level.priority) { - // Copy the reference to loggers so they are stable while iterating them. - val loggers = this.loggers - loggers.forEach { - it.log(category, level, throwable, message, *args) - } + ) { + if (level >= getLevel(SdkLogCategory)) { + doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) } } - /*** - * Internal method used to optimize logging from internal components. See - * [io.realm.kotlin.internal.ContextLogger] for more details. + /** + * Log a message. */ - internal inline fun doLog(category: LogCategory, level: LogLevel, throwable: Throwable?, message: () -> String?, vararg args: Any?) { - if (level.priority >= this.level.priority) { - // Copy the reference to loggers so they are stable while iterating them. - val loggers = this.loggers - val msg = message() - loggers.forEach { - it.log(category, level, throwable, msg, *args) - } - } + internal inline fun doLog( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) = loggers.forEach { + it.log(category, level, throwable, message, *args) } /** From 450d6cb279ff0c412b2491c468641652eb17beef Mon Sep 17 00:00:00 2001 From: Clemente Date: Tue, 14 May 2024 17:11:31 +0200 Subject: [PATCH 42/56] Refactor RealmLogger interface an ContextLogger --- .../kotlin/internal/platform/LogCatLogger.kt | 15 +++-- .../io/realm/kotlin/RealmConfiguration.kt | 2 +- .../kotlin/internal/platform/SystemUtils.kt | 3 +- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 10 ++- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 41 ------------ .../kotlin/internal/platform/StdOutLogger.kt | 11 +++- .../internal/platform/SystemUtilsJvm.kt | 5 +- .../kotlin/internal/platform/NSLogLogger.kt | 11 +++- .../kotlin/internal/platform/SystemUtils.kt | 5 +- .../realm/kotlin/mongodb/AppConfiguration.kt | 2 +- .../kotlin/mongodb/sync/SyncConfiguration.kt | 2 +- .../io/realm/kotlin/test/util/TestLogger.kt | 2 - .../realm/kotlin/test/common/RealmLogTests.kt | 65 ++----------------- .../io/realm/kotlin/test/common/RealmTests.kt | 3 + .../mongodb/common/HttpLogObfuscatorTests.kt | 6 +- .../common/SyncClientResetIntegrationTests.kt | 7 +- .../common/utils/CustomLogCollector.kt | 8 +-- 17 files changed, 60 insertions(+), 138 deletions(-) diff --git a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt index 022e152e38..a56e008826 100644 --- a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt +++ b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt @@ -16,11 +16,13 @@ package io.realm.kotlin.internal.platform import android.util.Log +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import java.io.PrintWriter import java.io.StringWriter import java.util.Locale +import kotlin.math.min /** * Create a logger that outputs to Android LogCat. @@ -29,11 +31,16 @@ import java.util.Locale * for message creation and formatting */ internal class LogCatLogger( - override val tag: String = "REALM", - override val level: LogLevel + private val tag: String, ) : RealmLogger { - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { val priority: Int = level.priority val logMessage: String = prepareLogMessage(throwable, message, *args) @@ -50,7 +57,7 @@ internal class LogCatLogger( var newline = logMessage.indexOf('\n', i) newline = if (newline != -1) newline else length do { - val end = Math.min(newline, i + MAX_LOG_LENGTH) + val end = min(newline, i + MAX_LOG_LENGTH) val part = logMessage.substring(i, end) printMessage(priority, part) i = end diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt index 4b46f62364..2ef946ca68 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt @@ -150,7 +150,7 @@ public interface RealmConfiguration : Configuration { override fun build(): RealmConfiguration { verifyConfig() - val realmLogger = ContextLogger("Sdk") + val realmLogger = ContextLogger() // Sync configs might not set 'name' but local configs always do, therefore it will // never be null here diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt index 81ec75a5f1..79322194e7 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt @@ -2,7 +2,6 @@ package io.realm.kotlin.internal.platform import io.realm.kotlin.internal.interop.SyncConnectionParams -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.types.RealmInstant import kotlin.jvm.JvmName @@ -123,7 +122,7 @@ public expect fun prepareRealmFilePath(directoryPath: String, filename: String): /** * Returns the default logger for the platform. */ -public expect fun createDefaultSystemLogger(tag: String, logLevel: LogLevel = LogLevel.NONE): RealmLogger +public expect fun createDefaultSystemLogger(tag: String): RealmLogger /** * Return the current thread id. diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 3a77c4bbe8..f478ef9d57 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -98,7 +98,7 @@ public object RealmLog { category, level, null, - if (message.isNullOrBlank()) { null } else { "[$category] $message" }, + message, ) } } @@ -387,7 +387,13 @@ public object RealmLog { message: String?, vararg args: Any?, ) = loggers.forEach { - it.log(category, level, throwable, message, *args) + it.log( + category = category, + level = level, + throwable = throwable, + message = if (message.isNullOrBlank()) { null } else { "[$category] $message" }, + args = *args + ) } /** diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index 9f5a24f252..ec5f24a095 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -24,18 +24,6 @@ import io.realm.kotlin.Configuration * @see Configuration.SharedBuilder.log */ public interface RealmLogger { - - /** - * The [LogLevel] used in this logger. - */ - @Deprecated("No longer in use") - public val level: LogLevel - - /** - * Tag that can be used to describe the output. - */ - public val tag: String - /** * Log an event. */ @@ -45,34 +33,5 @@ public interface RealmLogger { throwable: Throwable?, message: String?, vararg args: Any?, - ) { - log(level, throwable, message, *args) - } - - /** - * Log an event. - */ - @Deprecated( - "Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", - ReplaceWith("log") - ) - public fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { - TODO("log() shouldn't be called. Overwrite the category-variant instead") - } - - /** - * Log an event. - */ - @Deprecated( - "Use log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?)", - ReplaceWith("log") ) - public fun log(level: LogLevel, message: String) { - log( - category = LogCategory.Realm.Sdk, - level = level, - throwable = null, - message = message - ) - } } diff --git a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt index 36111e3c19..fd6a0a6e76 100644 --- a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt +++ b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt @@ -29,11 +29,16 @@ import java.util.* * Logger implementation outputting to stdout. */ internal class StdOutLogger( - override val tag: String = "REALM", - override val level: LogLevel + private val tag: String, ) : RealmLogger { - override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { val logMessage: String = prepareLogMessage(throwable, message, *args) val timestamp: String = getTimestamp() println("$timestamp ${level.name}: [$tag] $logMessage") diff --git a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsJvm.kt b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsJvm.kt index cedaba812b..b1eedc3a6f 100644 --- a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsJvm.kt +++ b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsJvm.kt @@ -4,7 +4,6 @@ import io.realm.kotlin.Realm import io.realm.kotlin.internal.RealmInstantImpl import io.realm.kotlin.internal.interop.SyncConnectionParams import io.realm.kotlin.internal.util.Exceptions -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.types.RealmInstant import java.io.InputStream @@ -28,8 +27,8 @@ public actual fun assetFileAsStream(assetFilename: String): InputStream { return resource.openStream() } -public actual fun createDefaultSystemLogger(tag: String, logLevel: LogLevel): RealmLogger = - StdOutLogger(tag, logLevel) +public actual fun createDefaultSystemLogger(tag: String): RealmLogger = + StdOutLogger(tag) /** * Since internalNow() should only logically return a value after the Unix epoch, it is safe to create a RealmInstant diff --git a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt index e0ef474a37..30ea7d35b0 100644 --- a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt +++ b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt @@ -28,11 +28,16 @@ import platform.Foundation.stringWithFormat * Inspiration from: https://github.com/touchlab/Kermit/blob/master/kermit/src/darwinMain/kotlin/co/touchlab/kermit/NSLogLogger.kt */ internal class NSLogLogger( - override val tag: String = "REALM", - override val level: LogLevel + private val tag: String, ) : RealmLogger { - override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log( + category: LogCategory, + level: LogLevel, + throwable: Throwable?, + message: String?, + vararg args: Any?, + ) { val logMessage: String = prepareLogMessage(throwable, message, *args) NSLog("%s: [%s] %s", level.name, tag, logMessage) } diff --git a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt index 7fbc206003..87ad3abf97 100644 --- a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt +++ b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/SystemUtils.kt @@ -3,7 +3,6 @@ package io.realm.kotlin.internal.platform import io.realm.kotlin.internal.RealmInstantImpl import io.realm.kotlin.internal.interop.SyncConnectionParams import io.realm.kotlin.internal.util.Exceptions -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.types.RealmInstant import kotlinx.cinterop.BooleanVar @@ -43,8 +42,8 @@ public actual val RUNTIME_VERSION: String = "" @Suppress("MayBeConst") // Cannot make expect/actual const public actual val PATH_SEPARATOR: String = "/" -public actual fun createDefaultSystemLogger(tag: String, logLevel: LogLevel): RealmLogger = - NSLogLogger(tag, logLevel) +public actual fun createDefaultSystemLogger(tag: String): RealmLogger = + NSLogLogger(tag) public actual fun threadId(): ULong { memScoped { diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt index d5e35e37b1..40fe525882 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt @@ -435,7 +435,7 @@ public interface AppConfiguration { CoroutineDispatcherFactory.managed("app-dispatcher-$appId") } - val appLogger = ContextLogger("Sdk") + val appLogger = ContextLogger() val networkTransport: (dispatcher: DispatcherHolder) -> NetworkTransport = { dispatcherHolder -> val logger: Logger = object : Logger { diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt index 6224e89df0..a62adefb5d 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt @@ -493,7 +493,7 @@ public interface SyncConfiguration : Configuration { @Suppress("LongMethod") override fun build(): SyncConfiguration { - val realmLogger = ContextLogger("Sdk") + val realmLogger = ContextLogger() // Set default error handler after setting config logging logic if (this.errorHandler == null) { diff --git a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt index 5a5a668793..eb5a716729 100644 --- a/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt +++ b/packages/test-base/src/commonMain/kotlin/io/realm/kotlin/test/util/TestLogger.kt @@ -8,8 +8,6 @@ import io.realm.kotlin.log.RealmLogger * Logger implementation that track latest log event, so we are able to inspect it. */ class TestLogger : RealmLogger { - override val tag: String = "IGNORE" - override val level: LogLevel = LogLevel.NONE var logLevel: LogLevel = LogLevel.NONE var throwable: Throwable? = null var message: String? = null diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 446e0362c6..e91e202e53 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -27,7 +27,6 @@ import io.realm.kotlin.test.util.Utils import kotlinx.atomicfu.atomic import kotlin.test.AfterTest import kotlin.test.BeforeTest -import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertContains import kotlin.test.assertEquals @@ -243,13 +242,12 @@ class RealmLogTests { fun deprecatedMethodWork1() { val called = atomic(false) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, - vararg args: Any? + vararg args: Any?, ) { assertEquals("Hello", message) called.value = true @@ -264,11 +262,12 @@ class RealmLogTests { fun deprecatedMethodWork2() { val called = atomic(false) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( + category: LogCategory, level: LogLevel, - message: String + throwable: Throwable?, + message: String?, + vararg args: Any?, ) { assertEquals("Hello", message) called.value = true @@ -283,8 +282,6 @@ class RealmLogTests { fun addLogger() { val called = atomic(false) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -306,8 +303,6 @@ class RealmLogTests { fun addLogger_twice() { val called = atomic(0) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -330,8 +325,6 @@ class RealmLogTests { fun removeLogger_success() { val called = atomic(0) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -353,8 +346,6 @@ class RealmLogTests { @Test fun removeLogger_falseForNonExistingLogger() { val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -371,8 +362,6 @@ class RealmLogTests { @Test fun removeAll_success() { val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -388,43 +377,6 @@ class RealmLogTests { RealmLog.trace("Hello") // Should not hit `fail()` } - @Test - fun addDeprecatedLogger_1() { - val called = atomic(false) - val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" - override fun log( - level: LogLevel, - throwable: Throwable?, - message: String?, - vararg args: Any?, - ) { - assertEquals("Hello", message) - called.value = true - } - } - RealmLog.add(customLogger) - RealmLog.trace("Hello") - assertTrue(called.value) - } - - @Test - fun addDeprecatedLogger_2() { - val called = atomic(false) - val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" - override fun log(level: LogLevel, message: String) { - assertEquals("Hello", message) - called.value = true - } - } - RealmLog.add(customLogger) - RealmLog.trace("Hello") - assertTrue(called.value) - } - @Test fun removeAll_falseIfNoLoggerWereRemoved() { assertTrue(RealmLog.removeAll()) @@ -479,12 +431,9 @@ class RealmLogTests { } @Test - @Ignore // https://jira.mongodb.org/browse/RKOTLIN-1076 fun filterSdkLogs() { val called = atomic(false) val customLogger = object : RealmLogger { - override val level: LogLevel = LogLevel.ALL - override val tag: String = "CUSTOM" override fun log( category: LogCategory, level: LogLevel, @@ -497,7 +446,7 @@ class RealmLogTests { } RealmLog.add(customLogger) - ContextLogger("Sdk").run { + ContextLogger().run { RealmLog.setLevel(LogLevel.NONE, LogCategory.Realm.Sdk) warn("should be filtered") assertFalse(called.value, "Unexpected message logged") diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index 5bf65df413..bd888eecf0 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,6 +28,8 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf +import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils @@ -72,6 +74,7 @@ class RealmTests { @BeforeTest fun setup() { + RealmLog.level = LogLevel.ALL tmpDir = PlatformUtils.createTempDir() configuration = RealmConfiguration.Builder(setOf(Parent::class, Child::class)) .directory(tmpDir) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt index b075ce09a7..62f114b94f 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt @@ -17,6 +17,7 @@ package io.realm.kotlin.test.mongodb.common import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.Credentials @@ -52,11 +53,8 @@ class HttpLogObfuscatorTests { private class ObfuscatorLoggerInspector( private val channel: Channel ) : RealmLogger { - - override val level: LogLevel = LogLevel.DEBUG - override val tag: String = "ObfuscatorLoggerInspector" - override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt index fcfa31f9f1..48675b733d 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt @@ -26,6 +26,7 @@ import io.realm.kotlin.ext.query import io.realm.kotlin.internal.interop.ErrorCode import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.runBlocking +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger @@ -306,12 +307,8 @@ class SyncClientResetIntegrationTests { val channel: Channel ) : RealmLogger { - override val level: LogLevel - get() = LogLevel.WARN - override val tag: String - get() = "SyncClientResetIntegrationTests" - override fun log( + category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/CustomLogCollector.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/CustomLogCollector.kt index e5d75483ee..0e14201e26 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/CustomLogCollector.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/utils/CustomLogCollector.kt @@ -16,6 +16,7 @@ package io.realm.kotlin.test.mongodb.common.utils +import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import kotlinx.coroutines.runBlocking @@ -25,10 +26,7 @@ import kotlinx.coroutines.sync.withLock /** * Logged collecting all logs it has seen. */ -class CustomLogCollector( - override val tag: String, - override val level: LogLevel -) : RealmLogger { +class CustomLogCollector : RealmLogger { private val mutex = Mutex() private val _logs = mutableListOf() @@ -42,7 +40,7 @@ class CustomLogCollector( } } - override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { + override fun log(category: LogCategory, level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) { val logMessage: String = message!! runBlocking { mutex.withLock { From 8c01bbfa2a63fe6e084e1d1c3982321fb8c348cc Mon Sep 17 00:00:00 2001 From: Clemente Date: Tue, 14 May 2024 17:29:34 +0200 Subject: [PATCH 43/56] move to internal --- .../kotlin/internal/platform/LogCatLogger.kt | 7 +- .../io/realm/kotlin/internal/LogUtils.kt | 68 +++++++++++++++++++ .../kotlin/io/realm/kotlin/log/LogCategory.kt | 13 +--- .../kotlin/io/realm/kotlin/log/LogLevel.kt | 45 +++++------- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 4 +- .../kotlin/internal/platform/StdOutLogger.kt | 8 ++- .../kotlin/internal/platform/NSLogLogger.kt | 8 ++- 7 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt diff --git a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt index a56e008826..dc6129d2ab 100644 --- a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt +++ b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/LogCatLogger.kt @@ -16,6 +16,7 @@ package io.realm.kotlin.internal.platform import android.util.Log +import io.realm.kotlin.internal.messageWithCategory import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger @@ -42,7 +43,11 @@ internal class LogCatLogger( vararg args: Any?, ) { val priority: Int = level.priority - val logMessage: String = prepareLogMessage(throwable, message, *args) + val logMessage: String = prepareLogMessage( + throwable = throwable, + message = messageWithCategory(category, message), + args = *args + ) // Short circuit if message can fit into a single line in LogCat if (logMessage.length < MAX_LOG_LENGTH) { diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt new file mode 100644 index 0000000000..4943bbb15a --- /dev/null +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2024 Realm 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.realm.kotlin.internal + +import io.realm.kotlin.internal.interop.CoreLogLevel +import io.realm.kotlin.log.LogCategory +import io.realm.kotlin.log.LogCategoryImpl +import io.realm.kotlin.log.LogLevel + + +internal fun LogLevel.toCoreLogLevel(): CoreLogLevel { + return when (this) { + LogLevel.ALL -> CoreLogLevel.RLM_LOG_LEVEL_ALL + LogLevel.TRACE -> CoreLogLevel.RLM_LOG_LEVEL_TRACE + LogLevel.DEBUG -> CoreLogLevel.RLM_LOG_LEVEL_DEBUG + LogLevel.INFO -> CoreLogLevel.RLM_LOG_LEVEL_INFO + LogLevel.WARN -> CoreLogLevel.RLM_LOG_LEVEL_WARNING + LogLevel.ERROR -> CoreLogLevel.RLM_LOG_LEVEL_ERROR + LogLevel.WTF -> CoreLogLevel.RLM_LOG_LEVEL_FATAL + LogLevel.NONE -> CoreLogLevel.RLM_LOG_LEVEL_OFF + } +} + +internal fun CoreLogLevel.fromCoreLogLevel(): LogLevel { + return when (this) { + CoreLogLevel.RLM_LOG_LEVEL_ALL -> LogLevel.ALL + CoreLogLevel.RLM_LOG_LEVEL_TRACE -> LogLevel.TRACE + CoreLogLevel.RLM_LOG_LEVEL_DEBUG, + CoreLogLevel.RLM_LOG_LEVEL_DETAIL -> LogLevel.DEBUG + CoreLogLevel.RLM_LOG_LEVEL_INFO -> LogLevel.INFO + CoreLogLevel.RLM_LOG_LEVEL_WARNING -> LogLevel.WARN + CoreLogLevel.RLM_LOG_LEVEL_ERROR -> LogLevel.ERROR + CoreLogLevel.RLM_LOG_LEVEL_FATAL -> LogLevel.WTF + CoreLogLevel.RLM_LOG_LEVEL_OFF -> LogLevel.NONE + else -> throw IllegalArgumentException("Invalid core log level: $this") + } +} + +internal fun newCategory( + name: String, + parent: LogCategory? = null, +): LogCategory = LogCategoryImpl(name, parent).also { category -> + categoriesByPath["$category"] = category +} + +// at package level as a workaround to ensure compatibility with darwin and jvm +internal val categoriesByPath: MutableMap = mutableMapOf() + +internal fun messageWithCategory( + category: LogCategory, + message: String?, +): String? = if (message.isNullOrBlank()) { null } else { + "[${category}] $message" // TODO: .toString().substring(6) +} \ No newline at end of file diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index aa1470b14f..1fb6064e92 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -16,6 +16,9 @@ package io.realm.kotlin.log +import io.realm.kotlin.internal.categoriesByPath +import io.realm.kotlin.internal.newCategory + /* * Core does not expose the different categories in compile time. * @@ -23,16 +26,6 @@ package io.realm.kotlin.log * in the kotlin type system, then validate it with a test watchdog. */ -// at package level as a workaround to ensure compatibility with darwin and jvm -private val categoriesByPath: MutableMap = mutableMapOf() - -internal fun newCategory( - name: String, - parent: LogCategory? = null, -): LogCategory = LogCategoryImpl(name, parent).also { category -> - categoriesByPath["$category"] = category -} - /** * Defines a log category for the Realm logger. */ diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt index e02ae3fb2f..fc1d2a89b0 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt @@ -1,6 +1,21 @@ +/* + * Copyright 2021 Realm 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.realm.kotlin.log -import io.realm.kotlin.internal.interop.CoreLogLevel import io.realm.kotlin.log.LogLevel.TRACE import io.realm.kotlin.log.LogLevel.WTF @@ -21,31 +36,3 @@ public enum class LogLevel(public val priority: Int) { WTF(6), NONE(7); } - -internal fun LogLevel.toCoreLogLevel(): CoreLogLevel { - return when (this) { - LogLevel.ALL -> CoreLogLevel.RLM_LOG_LEVEL_ALL - LogLevel.TRACE -> CoreLogLevel.RLM_LOG_LEVEL_TRACE - LogLevel.DEBUG -> CoreLogLevel.RLM_LOG_LEVEL_DEBUG - LogLevel.INFO -> CoreLogLevel.RLM_LOG_LEVEL_INFO - LogLevel.WARN -> CoreLogLevel.RLM_LOG_LEVEL_WARNING - LogLevel.ERROR -> CoreLogLevel.RLM_LOG_LEVEL_ERROR - LogLevel.WTF -> CoreLogLevel.RLM_LOG_LEVEL_FATAL - LogLevel.NONE -> CoreLogLevel.RLM_LOG_LEVEL_OFF - } -} - -internal fun CoreLogLevel.fromCoreLogLevel(): LogLevel { - return when (this) { - CoreLogLevel.RLM_LOG_LEVEL_ALL -> LogLevel.ALL - CoreLogLevel.RLM_LOG_LEVEL_TRACE -> LogLevel.TRACE - CoreLogLevel.RLM_LOG_LEVEL_DEBUG, - CoreLogLevel.RLM_LOG_LEVEL_DETAIL -> LogLevel.DEBUG - CoreLogLevel.RLM_LOG_LEVEL_INFO -> LogLevel.INFO - CoreLogLevel.RLM_LOG_LEVEL_WARNING -> LogLevel.WARN - CoreLogLevel.RLM_LOG_LEVEL_ERROR -> LogLevel.ERROR - CoreLogLevel.RLM_LOG_LEVEL_FATAL -> LogLevel.WTF - CoreLogLevel.RLM_LOG_LEVEL_OFF -> LogLevel.NONE - else -> throw IllegalArgumentException("Invalid core log level: $this") - } -} diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index f478ef9d57..4a9c5d4fa0 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -16,11 +16,13 @@ package io.realm.kotlin.log import io.realm.kotlin.Realm +import io.realm.kotlin.internal.fromCoreLogLevel import io.realm.kotlin.internal.interop.CoreLogLevel import io.realm.kotlin.internal.interop.LogCallback import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.internal.interop.SynchronizableObject import io.realm.kotlin.internal.platform.createDefaultSystemLogger +import io.realm.kotlin.internal.toCoreLogLevel import io.realm.kotlin.log.RealmLog.add import io.realm.kotlin.log.RealmLog.addDefaultSystemLogger @@ -391,7 +393,7 @@ public object RealmLog { category = category, level = level, throwable = throwable, - message = if (message.isNullOrBlank()) { null } else { "[$category] $message" }, + message = message, args = *args ) } diff --git a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt index fd6a0a6e76..a4179f4345 100644 --- a/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt +++ b/packages/library-base/src/jvmMain/kotlin/io/realm/kotlin/internal/platform/StdOutLogger.kt @@ -15,6 +15,7 @@ */ package io.realm.kotlin.internal.platform +import io.realm.kotlin.internal.messageWithCategory import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger @@ -23,7 +24,6 @@ import java.io.StringWriter import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter -import java.util.* /** * Logger implementation outputting to stdout. @@ -39,7 +39,11 @@ internal class StdOutLogger( message: String?, vararg args: Any?, ) { - val logMessage: String = prepareLogMessage(throwable, message, *args) + val logMessage: String = prepareLogMessage( + throwable = throwable, + message = messageWithCategory(category, message), + args = *args + ) val timestamp: String = getTimestamp() println("$timestamp ${level.name}: [$tag] $logMessage") } diff --git a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt index 30ea7d35b0..4b01fed2ca 100644 --- a/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt +++ b/packages/library-base/src/nativeDarwin/kotlin/io/realm/kotlin/internal/platform/NSLogLogger.kt @@ -15,6 +15,7 @@ */ package io.realm.kotlin.internal.platform +import io.realm.kotlin.internal.messageWithCategory import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger @@ -38,7 +39,12 @@ internal class NSLogLogger( message: String?, vararg args: Any?, ) { - val logMessage: String = prepareLogMessage(throwable, message, *args) + val logMessage: String = prepareLogMessage( + throwable = throwable, + message = messageWithCategory(category, message), + args = *args, + ) + NSLog("%s: [%s] %s", level.name, tag, logMessage) } From 510c94606e6691e0c8dbb215129cd32491a26b4f Mon Sep 17 00:00:00 2001 From: Clemente Date: Tue, 14 May 2024 17:30:26 +0200 Subject: [PATCH 44/56] ktlint --- .../commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt index 4943bbb15a..9318a0697c 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt @@ -21,7 +21,6 @@ import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogCategoryImpl import io.realm.kotlin.log.LogLevel - internal fun LogLevel.toCoreLogLevel(): CoreLogLevel { return when (this) { LogLevel.ALL -> CoreLogLevel.RLM_LOG_LEVEL_ALL @@ -64,5 +63,5 @@ internal fun messageWithCategory( category: LogCategory, message: String?, ): String? = if (message.isNullOrBlank()) { null } else { - "[${category}] $message" // TODO: .toString().substring(6) -} \ No newline at end of file + "[$category] $message" // todo .toString().substring(6) +} From 6f4d1e399a879f2422cf278b987d37b98b47d62a Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 15 May 2024 13:36:33 +0200 Subject: [PATCH 45/56] Clean up --- .../io/realm/kotlin/internal/platform/SystemUtilsAndroid.kt | 5 ++--- .../commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt | 2 +- .../src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt | 3 ++- .../kotlin/io/realm/kotlin/test/common/RealmTests.kt | 1 - .../io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsAndroid.kt b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsAndroid.kt index 166b961a13..45291eeabd 100644 --- a/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsAndroid.kt +++ b/packages/library-base/src/androidMain/kotlin/io/realm/kotlin/internal/platform/SystemUtilsAndroid.kt @@ -5,7 +5,6 @@ import io.realm.kotlin.internal.RealmInitializer import io.realm.kotlin.internal.RealmInstantImpl import io.realm.kotlin.internal.interop.SyncConnectionParams import io.realm.kotlin.internal.util.Exceptions -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.types.RealmInstant import java.io.FileNotFoundException @@ -37,8 +36,8 @@ public actual fun assetFileAsStream(assetFilename: String): InputStream = try { } // Returns the default logger for the platform -public actual fun createDefaultSystemLogger(tag: String, logLevel: LogLevel): RealmLogger = - LogCatLogger(tag, logLevel) +public actual fun createDefaultSystemLogger(tag: String): RealmLogger = + LogCatLogger(tag) public actual fun currentTime(): RealmInstant { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt index 9318a0697c..39630dfda9 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt @@ -63,5 +63,5 @@ internal fun messageWithCategory( category: LogCategory, message: String?, ): String? = if (message.isNullOrBlank()) { null } else { - "[$category] $message" // todo .toString().substring(6) + "[${category.name}] $message" } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 1fb6064e92..5f273d958f 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -31,6 +31,7 @@ import io.realm.kotlin.internal.newCategory */ public sealed interface LogCategory { public val parent: LogCategory? + public val name: String public operator fun contains(element: LogCategory): Boolean override fun toString(): String @@ -66,7 +67,7 @@ public sealed interface LogCategory { } internal class LogCategoryImpl( - internal val name: String, + override val name: String, override val parent: LogCategory? = null, ) : LogCategory { override fun contains(element: LogCategory): Boolean = "$element".contains("$this") diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index bd888eecf0..2398fa27bc 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -74,7 +74,6 @@ class RealmTests { @BeforeTest fun setup() { - RealmLog.level = LogLevel.ALL tmpDir = PlatformUtils.createTempDir() configuration = RealmConfiguration.Builder(setOf(Parent::class, Child::class)) .directory(tmpDir) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt index a51453089c..aca4ef0a1a 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt @@ -102,7 +102,7 @@ class SyncConfigTests { @Test fun logConfiguration() { val user = createTestUser() - val logger = createDefaultSystemLogger("TEST", LogLevel.DEBUG) + val logger = createDefaultSystemLogger("TEST") val customLoggers = listOf(logger) val config = SyncConfiguration.Builder( schema = PARTITION_BASED_SCHEMA, From 67bd60cc84919e5d3c9061ff0fe9c72f85a26ab7 Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 15 May 2024 15:32:53 +0200 Subject: [PATCH 46/56] Remove unused imports --- .../commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt index 2398fa27bc..5bf65df413 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmTests.kt @@ -28,8 +28,6 @@ import io.realm.kotlin.ext.version import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.isWindows import io.realm.kotlin.internal.platform.pathOf -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.query.find import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils From f669ee81d7dae628e83163854b6fd06e95b2770c Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 15 May 2024 15:34:49 +0200 Subject: [PATCH 47/56] Test fixes --- .../realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt | 2 +- .../io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt index 62f114b94f..bef3f11c9d 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt @@ -141,7 +141,7 @@ class HttpLogObfuscatorTests { @Test fun nullObfuscator() = runBlocking { - val logger = CustomLogCollector("NULL-OBFUSCATOR", LogLevel.DEBUG) + val logger = CustomLogCollector() app = TestApp( "nullObfuscator", appName = syncServerAppName("null-obf"), diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index 4f7884dcc8..a3174b57fd 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -1240,7 +1240,7 @@ class SyncedRealmTests { @Test fun customLoggersReceiveSyncLogs() = runBlocking { - val customLogger = CustomLogCollector("CUSTOM", LogLevel.ALL) + val customLogger = CustomLogCollector() val section = Random.nextInt() TestApp( "customLoggersReceiveSyncLogs", From 8640eb15271a0cc0cef3e29b6675ebd84767d542 Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 15 May 2024 18:27:58 +0200 Subject: [PATCH 48/56] Remove leftovers --- .../realm/kotlin/test/mongodb/common/AppConfigurationTests.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt index 0df15ed157..a5ab7c7ff9 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt @@ -403,9 +403,6 @@ class AppConfigurationTests { val channel = TestChannel() val logger = object : RealmLogger { - override val level: LogLevel = LogLevel.DEBUG - override val tag: String = "LOGGER" - override fun log( category: LogCategory, level: LogLevel, From 469e2333956335fe918d1424627004083b59361c Mon Sep 17 00:00:00 2001 From: Clemente Date: Wed, 15 May 2024 18:50:47 +0200 Subject: [PATCH 49/56] Remove redundant code --- .../io/realm/kotlin/internal/ContextLogger.kt | 17 +- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 207 +----------------- .../realm/kotlin/test/common/RealmLogTests.kt | 69 ++---- 3 files changed, 40 insertions(+), 253 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt index 82e3ba4e0a..3d8cd7df12 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt @@ -82,8 +82,19 @@ public class ContextLogger(public val context: String? = null) { doLog(LogLevel.WTF, null, { contextPrefix + message }, *args) } + private inline fun checkPriority( + level: LogLevel, + block: () -> Unit, + ) { + if (level.priority >= RealmLog.getLevel(SdkLogCategory).priority) { + block() + } + } + private inline fun doLog(level: LogLevel, throwable: Throwable?) { - RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, null) + checkPriority(level) { + RealmLog.log(LogCategory.Realm.Sdk, level, throwable, null) + } } private inline fun doLog( @@ -92,8 +103,8 @@ public class ContextLogger(public val context: String? = null) { message: () -> String?, vararg args: Any?, ) { - if (level >= RealmLog.getLevel(SdkLogCategory)) { - RealmLog.doLog(LogCategory.Realm.Sdk, level, throwable, message(), *args) + checkPriority(level) { + RealmLog.log(LogCategory.Realm.Sdk, level, throwable, message(), *args) } } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 4a9c5d4fa0..62e72d4b49 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -96,7 +96,7 @@ public object RealmLog { val category: LogCategory = LogCategory.fromCoreValue(categoryValue) val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() - doLog( + log( category, level, null, @@ -176,213 +176,10 @@ public object RealmLog { } } - /** - * Logs a [LogLevel.TRACE] event. - * - * @param throwable optional exception to log. - */ - internal fun trace(throwable: Throwable?) { - sdkLog(LogLevel.TRACE, throwable, null) - } - - /** - * Logs a [LogLevel.TRACE] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun trace(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.TRACE, throwable, message, *args) - } - - /** - * Logs a [LogLevel.TRACE] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun trace(message: String, vararg args: Any?) { - sdkLog(LogLevel.TRACE, null, message, *args) - } - - /** - * Logs a [LogLevel.DEBUG] event. - * - * @param throwable optional exception to log. - */ - internal fun debug(throwable: Throwable?) { - sdkLog(LogLevel.DEBUG, throwable, null) - } - - /** - * Logs a [LogLevel.DEBUG] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun debug(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.DEBUG, throwable, message, *args) - } - - /** - * Logs a [LogLevel.DEBUG] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun debug(message: String, vararg args: Any?) { - sdkLog(LogLevel.DEBUG, null, message, *args) - } - - /** - * Logs a [LogLevel.INFO] event. - * - * @param throwable optional exception to log. - */ - internal fun info(throwable: Throwable?) { - sdkLog(LogLevel.INFO, throwable, null) - } - - /** - * Logs a [LogLevel.INFO] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun info(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.INFO, throwable, message, *args) - } - - /** - * Logs a [LogLevel.INFO] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun info(message: String, vararg args: Any?) { - sdkLog(LogLevel.INFO, null, message, *args) - } - - /** - * Logs a [LogLevel.WARN] event. - * - * @param throwable optional exception to log. - */ - internal fun warn(throwable: Throwable?) { - sdkLog(LogLevel.WARN, throwable, null) - } - - /** - * Logs a [LogLevel.WARN] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun warn(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.WARN, throwable, message, *args) - } - - /** - * Logs a [LogLevel.INFO] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun warn(message: String, vararg args: Any?) { - sdkLog(LogLevel.WARN, null, message, *args) - } - - /** - * Logs a [LogLevel.ERROR] event. - * - * @param throwable optional exception to log. - */ - internal fun error(throwable: Throwable?) { - sdkLog(LogLevel.ERROR, throwable, null) - } - - /** - * Logs a [LogLevel.ERROR] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun error(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.ERROR, throwable, message, *args) - } - - /** - * Logs a [LogLevel.ERROR] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun error(message: String, vararg args: Any?) { - sdkLog(LogLevel.ERROR, null, message, *args) - } - - /** - * Logs a [LogLevel.WTF] event. - * - * @param throwable optional exception to log. - */ - internal fun wtf(throwable: Throwable?) { - sdkLog(LogLevel.WTF, throwable, null) - } - - /** - * Logs a [LogLevel.WTF] event. - * - * @param throwable optional exception to log. - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun wtf(throwable: Throwable?, message: String, vararg args: Any?) { - sdkLog(LogLevel.WTF, throwable, message, *args) - } - - /** - * Logs a [LogLevel.WTF] event. - * - * @param message optional message. - * @param args optional args used to format the message using a subset of `String.format` - * options. Only `%s`, `%d` and `%f` are supported. - */ - internal fun wtf(message: String, vararg args: Any?) { - sdkLog(LogLevel.WTF, null, message, *args) - } - - private inline fun sdkLog( - level: LogLevel, - throwable: Throwable?, - message: String?, - vararg args: Any?, - ) { - if (level >= getLevel(SdkLogCategory)) { - doLog(LogCategory.Realm.Sdk, level, throwable, message, *args) - } - } - /** * Log a message. */ - internal inline fun doLog( + internal inline fun log( category: LogCategory, level: LogLevel, throwable: Throwable?, diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index e91e202e53..8846d54dcf 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -17,6 +17,7 @@ package io.realm.kotlin.test.common import io.realm.kotlin.internal.ContextLogger +import io.realm.kotlin.internal.categoriesByPath import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel @@ -45,37 +46,12 @@ import kotlin.test.fail class RealmLogTests { private lateinit var existingLogLevel: LogLevel - private lateinit var log: RealmLog - - private val logCategories = listOf( - LogCategory.Realm, - - LogCategory.Realm.Storage, - LogCategory.Realm.Sync, - - LogCategory.Realm.Sync.Client, - - LogCategory.Realm.Sync.Client.Session, - LogCategory.Realm.Sync.Client.Changeset, - LogCategory.Realm.Sync.Client.Network, - LogCategory.Realm.Sync.Client.Reset, - - LogCategory.Realm.Sync.Server, - - LogCategory.Realm.App, - LogCategory.Realm.Sdk, - - LogCategory.Realm.Storage.Transaction, - LogCategory.Realm.Storage.Query, - LogCategory.Realm.Storage.Object, - LogCategory.Realm.Storage.Notification, - ) + private val log: ContextLogger = ContextLogger() @BeforeTest fun setUp() { existingLogLevel = RealmLog.level RealmLog.level = LogLevel.ALL - log = RealmLog } @AfterTest @@ -91,11 +67,11 @@ class RealmLogTests { RealmLog.apply { level = LogLevel.WARN add(customLogger) - warn("Testing 1") + log.warn("Testing 1") assertEquals("Testing 1", customLogger.message) - this.error("Testing 2") + log.error("Testing 2") assertEquals("Testing 2", customLogger.message) - info("Testing 3") // This should be swallowed + log.info("Testing 3") // This should be swallowed assertEquals("Testing 2", customLogger.message) } } @@ -109,7 +85,7 @@ class RealmLogTests { var message = "Testing" // Simple message - RealmLog.warn(message) + log.warn(message) assertEquals(LogLevel.WARN, customLogger.logLevel) assertNull(customLogger.throwable) assertEquals(message, customLogger.message) @@ -119,7 +95,7 @@ class RealmLogTests { val throwable = RuntimeException("BOOM") message = "Message: %s" val args: Array = arrayOf("foo") - RealmLog.error(throwable, message, *args) + log.error(throwable, message, *args) assertEquals(LogLevel.ERROR, customLogger.logLevel) assertEquals(throwable, customLogger.throwable) assertEquals(message, customLogger.message) @@ -254,7 +230,7 @@ class RealmLogTests { } } RealmLog.add(customLogger) - RealmLog.trace("Hello") + log.trace("Hello") assertTrue(called.value) } @@ -274,7 +250,7 @@ class RealmLogTests { } } RealmLog.add(customLogger) - RealmLog.trace("Hello") + log.trace("Hello") assertTrue(called.value) } @@ -295,7 +271,7 @@ class RealmLogTests { } } RealmLog.add(customLogger) - RealmLog.trace("Hello") + log.trace("Hello") assertTrue(called.value) } @@ -317,7 +293,7 @@ class RealmLogTests { } RealmLog.add(customLogger) RealmLog.add(customLogger) - RealmLog.trace("Hello") + log.trace("Hello") assertEquals(2, called.value) } @@ -374,7 +350,7 @@ class RealmLogTests { } RealmLog.add(customLogger) assertTrue(RealmLog.removeAll()) - RealmLog.trace("Hello") // Should not hit `fail()` + log.trace("Hello") // Should not hit `fail()` } @Test @@ -396,14 +372,16 @@ class RealmLogTests { @Test fun setCategoryLevels() { - logCategories.forEach { logCategory -> - val previousLevel: LogLevel = RealmLog.getLevel(logCategory) - RealmLog.setLevel(LogLevel.TRACE, logCategory) - assertEquals(LogLevel.TRACE, RealmLog.getLevel(logCategory)) - - // Restore the level to whatever it was set before - RealmLog.setLevel(previousLevel, logCategory) - } + categoriesByPath + .values + .forEach { logCategory -> + val previousLevel: LogLevel = RealmLog.getLevel(logCategory) + RealmLog.setLevel(LogLevel.TRACE, logCategory) + assertEquals(LogLevel.TRACE, RealmLog.getLevel(logCategory)) + + // Restore the level to whatever it was set before + RealmLog.setLevel(previousLevel, logCategory) + } } @Test @@ -419,7 +397,8 @@ class RealmLogTests { fun categoriesWatchdog() { val coreLogCategoryNames = RealmInterop.realm_get_category_names() - val logCategoriesPaths = logCategories.map { "$it" } + val logCategoriesPaths = categoriesByPath + .keys logCategoriesPaths.forEach { path -> assertContains(coreLogCategoryNames, path) From acf8f57a1847dc10be59491ef678d9dbc7b2f98a Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 00:32:46 +0200 Subject: [PATCH 50/56] Remove obsolete code --- .../kotlin/io/realm/kotlin/Configuration.kt | 46 ------------------- .../io/realm/kotlin/RealmConfiguration.kt | 11 ----- .../kotlin/internal/ConfigurationImpl.kt | 9 +--- .../io/realm/kotlin/internal/ContextLogger.kt | 5 +- .../kotlin/internal/RealmConfigurationImpl.kt | 3 -- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 4 +- .../kotlin/io/realm/kotlin/log/RealmLogger.kt | 4 +- .../mongodb/internal/RealmSyncInitializer.kt | 12 +++-- .../realm/kotlin/mongodb/AppConfiguration.kt | 39 +--------------- .../mongodb/internal/AppConfigurationImpl.kt | 4 +- .../realm/kotlin/mongodb/internal/AppImpl.kt | 7 ++- .../mongodb/internal/SyncConfigurationImpl.kt | 3 +- .../kotlin/mongodb/sync/SyncConfiguration.kt | 24 ---------- .../test/common/RealmConfigurationTests.kt | 34 -------------- .../test/common/VersionTrackingTests.kt | 2 +- .../io/realm/kotlin/test/mongodb/TestApp.kt | 15 +----- .../test/mongodb/common/SyncConfigTests.kt | 17 ------- .../test/mongodb/common/SyncedRealmTests.kt | 44 ------------------ 18 files changed, 23 insertions(+), 260 deletions(-) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/Configuration.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/Configuration.kt index daf8e6a42f..cd261b23bf 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/Configuration.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/Configuration.kt @@ -21,9 +21,6 @@ import io.realm.kotlin.internal.MISSING_PLUGIN_MESSAGE import io.realm.kotlin.internal.REALM_FILE_EXTENSION import io.realm.kotlin.internal.platform.PATH_SEPARATOR import io.realm.kotlin.internal.realmObjectCompanionOrNull -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog -import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.types.BaseRealmObject import kotlinx.coroutines.CoroutineDispatcher import kotlin.reflect.KClass @@ -74,23 +71,6 @@ public fun interface InitialDataCallback { public fun MutableRealm.write() } -/** - * Configuration for log events created by a Realm instance. - */ -@Deprecated("Use io.realm.kotlin.log.RealmLog instead.") -public data class LogConfiguration( - /** - * The [LogLevel] for which all log events of equal or higher priority will be reported. - */ - public val level: LogLevel, - - /** - * Any loggers to install. They will receive all log events with a priority equal to or higher - * than the value defined in [LogConfiguration.level]. - */ - public val loggers: List -) - /** * Configuration for pre-bundled asset files used as initial state of the realm file. */ @@ -126,12 +106,6 @@ public interface Configuration { */ public val schema: Set> - /** - * The log configuration used for the realm instance. - */ - @Deprecated("Use io.realm.kotlin.log.RealmLog instead.") - public val log: LogConfiguration - /** * Maximum number of active versions. * @@ -226,9 +200,6 @@ public interface Configuration { // 'name' must be nullable as it is optional when getting SyncClient's default path! protected abstract var name: String? - protected var logLevel: LogLevel = RealmLog.level - protected var appConfigLoggers: List = listOf() - protected var realmConfigLoggers: List = listOf() protected var maxNumberOfActiveVersions: Long = Long.MAX_VALUE protected var notificationDispatcher: CoroutineDispatcher? = null protected var writeDispatcher: CoroutineDispatcher? = null @@ -282,23 +253,6 @@ public interface Configuration { this.maxNumberOfActiveVersions = maxVersions } as S - /** - * Configure how Realm will report log events. - * - * @param level all events at this level or higher will be reported. - * @param customLoggers any custom loggers to send log events to. A default system logger is - * installed by default that will redirect to the common logging framework on the platform, - * i.e. LogCat on Android and NSLog on iOS. - */ - @Deprecated("Use io.realm.kotlin.log.RealmLog instead.") - public open fun log( - level: LogLevel = LogLevel.WARN, - customLoggers: List = emptyList() - ): S = apply { - this.logLevel = level - this.realmConfigLoggers = customLoggers - } as S - /** * Dispatcher on which Realm notifications are run. It is possible to listen for changes to * Realm objects from any thread, but the underlying logic will run on this dispatcher diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt index 2ef946ca68..7ef592841c 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/RealmConfiguration.kt @@ -20,8 +20,6 @@ import io.realm.kotlin.internal.ContextLogger import io.realm.kotlin.internal.RealmConfigurationImpl import io.realm.kotlin.internal.platform.appFilesDirectory import io.realm.kotlin.internal.util.CoroutineDispatcherFactory -import io.realm.kotlin.log.RealmLog -import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.migration.AutomaticSchemaMigration import io.realm.kotlin.migration.RealmMigration import io.realm.kotlin.types.TypedRealmObject @@ -167,19 +165,10 @@ public interface RealmConfiguration : Configuration { } else { CoroutineDispatcherFactory.managed("writer-$fileName") } - - // Configure logging during creation of a (Realm/Sync)Configuration to keep old behavior - // for configuring logging. This should be removed when `LogConfiguration` is removed. - RealmLog.level = logLevel - realmConfigLoggers.forEach { RealmLog.add(it) } - @Suppress("invisible_reference", "invisible_member") - val allLoggers: List = listOf(RealmLog.systemLoggerInstalled).filterNotNull() + realmConfigLoggers - return RealmConfigurationImpl( directory, fileName, schema, - LogConfiguration(logLevel, allLoggers), maxNumberOfActiveVersions, notificationDispatcherFactory, writerDispatcherFactory, diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ConfigurationImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ConfigurationImpl.kt index 95942392a4..6b2d3a234a 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ConfigurationImpl.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ConfigurationImpl.kt @@ -19,7 +19,6 @@ package io.realm.kotlin.internal import io.realm.kotlin.CompactOnLaunchCallback import io.realm.kotlin.InitialDataCallback import io.realm.kotlin.InitialRealmFileConfiguration -import io.realm.kotlin.LogConfiguration import io.realm.kotlin.dynamic.DynamicMutableRealm import io.realm.kotlin.dynamic.DynamicMutableRealmObject import io.realm.kotlin.dynamic.DynamicRealm @@ -53,7 +52,6 @@ public open class ConfigurationImpl( directory: String, name: String, schema: Set>, - logConfig: LogConfiguration, maxNumberOfActiveVersions: Long, notificationDispatcher: CoroutineDispatcherFactory, writeDispatcher: CoroutineDispatcherFactory, @@ -67,7 +65,7 @@ public open class ConfigurationImpl( override val isFlexibleSyncConfiguration: Boolean, inMemory: Boolean, initialRealmFileConfiguration: InitialRealmFileConfiguration?, - logger: ContextLogger + override val logger: ContextLogger ) : InternalConfiguration { final override val path: String @@ -76,16 +74,12 @@ public open class ConfigurationImpl( final override val schema: Set> - final override val log: LogConfiguration - final override val maxNumberOfActiveVersions: Long final override val schemaVersion: Long final override val schemaMode: SchemaMode - override val logger: ContextLogger = logger - override val encryptionKey: ByteArray? get(): ByteArray? = userEncryptionKey @@ -138,7 +132,6 @@ public open class ConfigurationImpl( this.name = name this.schema = schema this.mapOfKClassWithCompanion = schema.associateWith { realmObjectCompanionOrThrow(it) } - this.log = logConfig this.maxNumberOfActiveVersions = maxNumberOfActiveVersions this.notificationDispatcherFactory = notificationDispatcher this.writeDispatcherFactory = writeDispatcher diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt index 3d8cd7df12..2b1efbc1b1 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt @@ -1,6 +1,5 @@ package io.realm.kotlin.internal -import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.SdkLogCategory @@ -93,7 +92,7 @@ public class ContextLogger(public val context: String? = null) { private inline fun doLog(level: LogLevel, throwable: Throwable?) { checkPriority(level) { - RealmLog.log(LogCategory.Realm.Sdk, level, throwable, null) + RealmLog.doLog(SdkLogCategory, level, throwable, null) } } @@ -104,7 +103,7 @@ public class ContextLogger(public val context: String? = null) { vararg args: Any?, ) { checkPriority(level) { - RealmLog.log(LogCategory.Realm.Sdk, level, throwable, message(), *args) + RealmLog.doLog(SdkLogCategory, level, throwable, message(), *args) } } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmConfigurationImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmConfigurationImpl.kt index 972f8c5386..4ca59cb4e7 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmConfigurationImpl.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmConfigurationImpl.kt @@ -19,7 +19,6 @@ package io.realm.kotlin.internal import io.realm.kotlin.CompactOnLaunchCallback import io.realm.kotlin.InitialDataCallback import io.realm.kotlin.InitialRealmFileConfiguration -import io.realm.kotlin.LogConfiguration import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.internal.interop.SchemaMode import io.realm.kotlin.internal.util.CoroutineDispatcherFactory @@ -34,7 +33,6 @@ internal class RealmConfigurationImpl( directory: String, name: String, schema: Set>, - logConfig: LogConfiguration, maxNumberOfActiveVersions: Long, notificationDispatcherFactory: CoroutineDispatcherFactory, writeDispatcherFactory: CoroutineDispatcherFactory, @@ -52,7 +50,6 @@ internal class RealmConfigurationImpl( directory, name, schema, - logConfig, maxNumberOfActiveVersions, notificationDispatcherFactory, writeDispatcherFactory, diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 62e72d4b49..9705c0d79d 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -96,7 +96,7 @@ public object RealmLog { val category: LogCategory = LogCategory.fromCoreValue(categoryValue) val level: LogLevel = CoreLogLevel.valueFromPriority(logLevel).fromCoreLogLevel() - log( + doLog( category, level, null, @@ -179,7 +179,7 @@ public object RealmLog { /** * Log a message. */ - internal inline fun log( + internal inline fun doLog( category: LogCategory, level: LogLevel, throwable: Throwable?, diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt index ec5f24a095..6546fbd9e0 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLogger.kt @@ -16,12 +16,10 @@ package io.realm.kotlin.log -import io.realm.kotlin.Configuration - /** * Interface describing a logger implementation. * - * @see Configuration.SharedBuilder.log + * @see RealmLog */ public interface RealmLogger { /** diff --git a/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt b/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt index 813576267b..c91070d5f3 100644 --- a/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt +++ b/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt @@ -28,8 +28,8 @@ import android.net.NetworkInfo import android.net.NetworkRequest import android.os.Build import androidx.startup.Initializer +import io.realm.kotlin.internal.ContextLogger import io.realm.kotlin.internal.RealmInitializer -import io.realm.kotlin.log.RealmLog /** * An **initializer** for Sync specific functionality that does not fit into the `RealmInitializer` @@ -38,6 +38,8 @@ import io.realm.kotlin.log.RealmLog internal class RealmSyncInitializer : Initializer { companion object { + val logger: ContextLogger = ContextLogger() + @Suppress("DEPRECATION") // Should only be called below API 21 fun isConnected(cm: ConnectivityManager?): Boolean { return cm?.let { @@ -85,7 +87,7 @@ internal class RealmSyncInitializer : Initializer { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M /* 23 */) { request.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) } - RealmLog.info("Register ConnectivityManager network callbacks") + logger.info("Register ConnectivityManager network callbacks") connectivityManager?.registerNetworkCallback( request.build(), object : NetworkCallback() { @@ -99,7 +101,7 @@ internal class RealmSyncInitializer : Initializer { } ) } else { - RealmLog.info("Register BroadcastReceiver connectivity callbacks") + logger.info("Register BroadcastReceiver connectivity callbacks") @Suppress("DEPRECATION") context.registerReceiver( object : BroadcastReceiver() { @@ -112,10 +114,10 @@ internal class RealmSyncInitializer : Initializer { ) } } catch (ex: Exception) { - RealmLog.warn("Something went wrong trying to register a network state listener: $ex") + logger.warn("Something went wrong trying to register a network state listener: $ex") } } else { - RealmLog.warn( + logger.warn( "It was not possible to register a network state listener. " + "ACCESS_NETWORK_STATE was not granted." ) diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt index 40fe525882..41dbad1494 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/AppConfiguration.kt @@ -16,7 +16,6 @@ package io.realm.kotlin.mongodb import io.ktor.client.plugins.logging.Logger -import io.realm.kotlin.LogConfiguration import io.realm.kotlin.Realm import io.realm.kotlin.annotations.ExperimentalRealmSerializerApi import io.realm.kotlin.internal.ContextLogger @@ -31,9 +30,6 @@ import io.realm.kotlin.internal.platform.prepareRealmDirectoryPath import io.realm.kotlin.internal.util.CoroutineDispatcherFactory import io.realm.kotlin.internal.util.DispatcherHolder import io.realm.kotlin.internal.util.Validation -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog -import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.ext.customData import io.realm.kotlin.mongodb.ext.profile import io.realm.kotlin.mongodb.internal.AppConfigurationImpl @@ -158,9 +154,7 @@ public interface AppConfiguration { private var baseUrl: String = DEFAULT_BASE_URL private var dispatcher: CoroutineDispatcher? = null private var encryptionKey: ByteArray? = null - private var logLevel: LogLevel? = null private var syncRootDirectory: String = appFilesDirectory() - private var userLoggers: List = listOf() private var networkTransport: NetworkTransport? = null private var websocketTransport: WebSocketTransport? = null private var appName: String? = null @@ -209,25 +203,6 @@ public interface AppConfiguration { this.dispatcher = dispatcher } - /** - * Configures how Realm will report log events for this App. - * - * @param level all events at this level or higher will be reported. - * @param customLoggers any custom loggers to send log events to. A default system logger is - * installed by default that will redirect to the common logging framework on the platform, i.e. - * LogCat on Android and NSLog on iOS. - * @return the Builder instance used. - */ - @Deprecated("Use io.realm.kotlin.log.RealmLog instead.") - public fun log( - level: LogLevel = LogLevel.WARN, - customLoggers: List = emptyList(), - ): Builder = - apply { - this.logLevel = level - this.userLoggers = customLoggers - } - /** * Configures the root folder that marks the location of a `mongodb-realm` folder. This * folder contains all files and realms used when synchronizing data between the device and @@ -414,18 +389,6 @@ public interface AppConfiguration { // to this method. @OptIn(ExperimentalKBsonSerializerApi::class) public fun build(bundleId: String): AppConfiguration { - // Configure logging during creation of AppConfiguration to keep old behavior for - // configuring logging. This should be removed when `LogConfiguration` is removed. - val allLoggers = mutableListOf() - allLoggers.addAll(userLoggers) - - val logConfig = this.logLevel?.let { - RealmLog.level = it - LogConfiguration(it, allLoggers) - } - - userLoggers.forEach { RealmLog.add(it) } - val appNetworkDispatcherFactory = if (dispatcher != null) { CoroutineDispatcherFactory.unmanaged(dispatcher!!) } else { @@ -474,7 +437,6 @@ public interface AppConfiguration { networkTransportFactory = networkTransport, websocketTransport = websocketTransport, syncRootDirectory = syncRootDirectory, - logger = logConfig, appName = appName, appVersion = appVersion, bundleId = bundleId, @@ -484,6 +446,7 @@ public interface AppConfiguration { authorizationHeaderName = authorizationHeaderName, enableSessionMultiplexing = enableSessionMultiplexing, syncTimeoutOptions = syncTimeoutOptions, + logger = appLogger ) } } diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppConfigurationImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppConfigurationImpl.kt index 0943b8c668..d172d6c173 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppConfigurationImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppConfigurationImpl.kt @@ -16,7 +16,7 @@ package io.realm.kotlin.mongodb.internal -import io.realm.kotlin.LogConfiguration +import io.realm.kotlin.internal.ContextLogger import io.realm.kotlin.internal.SDK_VERSION import io.realm.kotlin.internal.interop.RealmAppConfigurationPointer import io.realm.kotlin.internal.interop.RealmInterop @@ -51,7 +51,6 @@ public class AppConfigurationImpl @OptIn(ExperimentalKBsonSerializerApi::class) private val websocketTransport: WebSocketTransport?, override val metadataMode: MetadataMode, override val syncRootDirectory: String, - public val logger: LogConfiguration?, override val appName: String?, override val appVersion: String?, internal val bundleId: String, @@ -61,6 +60,7 @@ public class AppConfigurationImpl @OptIn(ExperimentalKBsonSerializerApi::class) override val authorizationHeaderName: String, override val enableSessionMultiplexing: Boolean, override val syncTimeoutOptions: SyncTimeoutOptions, + public val logger: ContextLogger, ) : AppConfiguration { /** diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppImpl.kt index 870e08de95..2ea4681ff6 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppImpl.kt @@ -25,7 +25,6 @@ import io.realm.kotlin.internal.toDuration import io.realm.kotlin.internal.util.DispatcherHolder import io.realm.kotlin.internal.util.Validation import io.realm.kotlin.internal.util.use -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.AppConfiguration import io.realm.kotlin.mongodb.AuthenticationChange @@ -93,15 +92,15 @@ public class AppImpl( // Due to the way network interfaces are re-enabled on Android, we might see multiple // "isOnline" messages in short order. So in order to prevent resetting the network // too often we throttle messages, so a reconnect can only happen ever 5 seconds. - RealmLog.debug("Network state change detected. ConnectionAvailable = $connectionAvailable") + configuration.logger.debug("Network state change detected. ConnectionAvailable = $connectionAvailable") val now: Duration = RealmInstant.now().toDuration() if (connectionAvailable && (lastOnlineStateReported == null || now.minus(lastOnlineStateReported!!) > reconnectThreshold) ) { - RealmLog.info("Trigger network reconnect.") + configuration.logger.info("Trigger network reconnect.") try { sync.reconnect() } catch (ex: Exception) { - RealmLog.error(ex.toString()) + configuration.logger.error(ex.toString()) } lastOnlineStateReported = now } diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/SyncConfigurationImpl.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/SyncConfigurationImpl.kt index 1a06d2a32f..ddcf819081 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/SyncConfigurationImpl.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/SyncConfigurationImpl.kt @@ -36,7 +36,6 @@ import io.realm.kotlin.internal.interop.SyncErrorCallback import io.realm.kotlin.internal.interop.sync.SyncError import io.realm.kotlin.internal.interop.sync.SyncSessionResyncMode import io.realm.kotlin.internal.platform.fileExists -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.mongodb.exceptions.ClientResetRequiredException import io.realm.kotlin.mongodb.exceptions.DownloadingRealmTimeOutException import io.realm.kotlin.mongodb.subscriptions @@ -223,7 +222,7 @@ internal class SyncConfigurationImpl( } } catch (ex: Exception) { @Suppress("invisible_member", "invisible_reference") - RealmLog.error("Error thrown and ignored in `onManualResetFallback`: $ex") + configuration.logger.error("Error thrown and ignored in `onManualResetFallback`: $ex") } } else { userErrorHandler.onError(session, syncError) diff --git a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt index a62adefb5d..943a6d610c 100644 --- a/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt +++ b/packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/sync/SyncConfiguration.kt @@ -16,7 +16,6 @@ package io.realm.kotlin.mongodb.sync import io.realm.kotlin.Configuration -import io.realm.kotlin.LogConfiguration import io.realm.kotlin.MutableRealm import io.realm.kotlin.Realm import io.realm.kotlin.TypedRealm @@ -27,9 +26,6 @@ import io.realm.kotlin.internal.interop.RealmInterop import io.realm.kotlin.internal.interop.SchemaMode import io.realm.kotlin.internal.platform.PATH_SEPARATOR import io.realm.kotlin.internal.util.CoroutineDispatcherFactory -import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog -import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.AppConfiguration import io.realm.kotlin.mongodb.Credentials @@ -373,11 +369,6 @@ public interface SyncConfiguration : Configuration { if (!user.loggedIn) { throw IllegalArgumentException("A valid, logged in user is required.") } - // Prime builder with log configuration from AppConfiguration - (user as UserImpl).app.configuration.logger?.let { appLog -> - this.logLevel = appLog.level - this.appConfigLoggers = appLog.loggers - } } /** @@ -401,13 +392,6 @@ public interface SyncConfiguration : Configuration { this.syncClientResetStrategy = resetStrategy } - override fun log(level: LogLevel, customLoggers: List): Builder = - apply { - // Will clear any primed configuration - this.logLevel = level - this.realmConfigLoggers = customLoggers - } - /** * Sets the filename of the realm file. * @@ -539,18 +523,10 @@ public interface SyncConfiguration : Configuration { val fileName = fullPathToFile.substringAfterLast(PATH_SEPARATOR) val directory = fullPathToFile.removeSuffix("$PATH_SEPARATOR$fileName") - // Configure logging during creation of a (Realm/Sync)Configuration to keep old behavior - // for configuring logging. This should be removed when `LogConfiguration` is removed. - RealmLog.level = logLevel - realmConfigLoggers.forEach { RealmLog.add(it) } - @Suppress("invisible_reference", "invisible_member") - val allLoggers: List = listOf(RealmLog.systemLoggerInstalled).filterNotNull() + appConfigLoggers + realmConfigLoggers - val baseConfiguration = ConfigurationImpl( directory, fileName, schema, - LogConfiguration(logLevel, allLoggers), maxNumberOfActiveVersions, if (notificationDispatcher != null) { CoroutineDispatcherFactory.unmanaged(notificationDispatcher!!) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index 002ce4719a..2d3bbabf6f 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -32,7 +32,6 @@ import io.realm.kotlin.migration.AutomaticSchemaMigration import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils import io.realm.kotlin.test.platform.platformFileSystem -import io.realm.kotlin.test.util.TestLogger import io.realm.kotlin.test.util.use import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.newSingleThreadContext @@ -242,39 +241,6 @@ class RealmConfigurationTests { Realm.open(config).use { } } - @Test - fun defaultLogLevel() { - val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) - .build() - assertEquals(LogLevel.WARN, config.log.level) - assertEquals(LogLevel.WARN, RealmLog.level) - } - - @Test - fun logLevel() { - val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) - .log(LogLevel.NONE) - .build() - assertEquals(LogLevel.NONE, config.log.level) - } - - @Test - fun defaultCustomLoggers() { - val config: RealmConfiguration = - RealmConfiguration.Builder(schema = setOf(Sample::class)).build() - assertEquals(1, config.log.loggers.size) - } - - @Test - fun customLoggers() { - val logger = TestLogger() - val config: RealmConfiguration = RealmConfiguration.Builder(schema = setOf(Sample::class)) - .log(customLoggers = listOf(logger)) - .build() - assertEquals(2, config.log.loggers.size) - assertEquals(logger, config.log.loggers.last()) - } - @Test fun defaultMaxNumberOfActiveVersions() { val config = RealmConfiguration.create(schema = setOf(Sample::class)) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt index 1dc47b670d..77fb6ed574 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt @@ -65,7 +65,7 @@ class VersionTrackingTests { Sample::class, SampleWithPrimaryKey::class ) + embeddedSchema - ).directory(tmpDir).log(LogLevel.DEBUG).build() + ).directory(tmpDir).build() realm = Realm.open(configuration) } diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt index fd8e95a59f..38c237c193 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt @@ -27,12 +27,12 @@ import io.realm.kotlin.internal.interop.sync.NetworkTransport import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.internal.platform.singleThreadDispatcher import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.AppConfiguration import io.realm.kotlin.mongodb.Credentials import io.realm.kotlin.mongodb.User +import io.realm.kotlin.mongodb.internal.AppConfigurationImpl import io.realm.kotlin.mongodb.sync.SyncConfiguration import io.realm.kotlin.test.mongodb.common.FLEXIBLE_SYNC_SCHEMA import io.realm.kotlin.test.mongodb.util.AppAdmin @@ -114,8 +114,6 @@ open class TestApp private constructor( build( debug = debug, appName = appName, - logLevel = logLevel, - customLogger = customLogger, dispatcher = dispatcher, builder = builder, networkTransport = networkTransport, @@ -173,7 +171,7 @@ open class TestApp private constructor( // Some tests might render the server inaccessible, preventing us from // deleting users. Assume those tests know what they are doing and // ignore errors here. - RealmLog.warn("Server side users could not be deleted: $ex") + (configuration as AppConfigurationImpl).logger.warn("Server side users could not be deleted: $ex") } } @@ -203,8 +201,6 @@ open class TestApp private constructor( fun build( debug: Boolean, appName: String, - logLevel: LogLevel?, - customLogger: RealmLogger?, dispatcher: CoroutineDispatcher, builder: (AppConfiguration.Builder) -> AppConfiguration.Builder, networkTransport: NetworkTransport?, @@ -229,13 +225,6 @@ open class TestApp private constructor( .networkTransport(networkTransport) .ejson(ejson) .apply { - if (logLevel != null) { - log( - logLevel, - if (customLogger == null) emptyList() - else listOf(customLogger) - ) - } if (SyncServerConfig.usePlatformNetworking) { usePlatformNetworking() } diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt index aca4ef0a1a..fc7a47893a 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt @@ -29,7 +29,6 @@ import io.realm.kotlin.entities.sync.flx.FlexChildObject import io.realm.kotlin.entities.sync.flx.FlexEmbeddedObject import io.realm.kotlin.entities.sync.flx.FlexParentObject import io.realm.kotlin.ext.query -import io.realm.kotlin.internal.platform.createDefaultSystemLogger import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.internal.platform.singleThreadDispatcher @@ -99,22 +98,6 @@ class SyncConfigTests { RealmLog.reset() } - @Test - fun logConfiguration() { - val user = createTestUser() - val logger = createDefaultSystemLogger("TEST") - val customLoggers = listOf(logger) - val config = SyncConfiguration.Builder( - schema = PARTITION_BASED_SCHEMA, - user = user, - partitionValue = partitionValue - ).also { builder -> - builder.log(LogLevel.DEBUG, customLoggers) - }.build() - assertEquals(LogLevel.DEBUG, config.log.level) - assertEquals(logger, config.log.loggers[1]) // Additional logger placed after default logger - } - @Test fun errorHandler() { val errorHandler = object : SyncSession.ErrorHandler { diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index a3174b57fd..a28962d787 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -16,7 +16,6 @@ package io.realm.kotlin.test.mongodb.common -import io.realm.kotlin.LogConfiguration import io.realm.kotlin.Realm import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.VersionId @@ -54,7 +53,6 @@ import io.realm.kotlin.schema.RealmSchema import io.realm.kotlin.schema.ValuePropertyType import io.realm.kotlin.test.mongodb.TestApp import io.realm.kotlin.test.mongodb.asTestApp -import io.realm.kotlin.test.mongodb.common.utils.CustomLogCollector import io.realm.kotlin.test.mongodb.common.utils.assertFailsWithMessage import io.realm.kotlin.test.mongodb.common.utils.uploadAllLocalChangesOrFail import io.realm.kotlin.test.mongodb.createUserAndLogIn @@ -1238,44 +1236,6 @@ class SyncedRealmTests { } } - @Test - fun customLoggersReceiveSyncLogs() = runBlocking { - val customLogger = CustomLogCollector() - val section = Random.nextInt() - TestApp( - "customLoggersReceiveSyncLogs", - appName = io.realm.kotlin.test.mongodb.TEST_APP_FLEX, - builder = { - it.syncRootDirectory(PlatformUtils.createTempDir("flx-sync-")) - it.log(level = LogLevel.ALL, listOf(customLogger)) - it.appName("MyCustomApp") - it.appVersion("1.0.0") - } - ).use { flexApp -> - val (email, password) = randomEmail() to "password1234" - val user = flexApp.createUserAndLogIn(email, password) - val syncConfig = createFlexibleSyncConfig( - user = user, - name = "flex.realm", - initialSubscriptions = { realm: Realm -> - realm.query("section = $0", section).subscribe() - } - ) - Realm.open(syncConfig).use { flexSyncRealm: Realm -> - flexSyncRealm.writeBlocking { - copyToRealm( - FlexParentObject().apply { - name = "local object" - } - ) - } - flexSyncRealm.syncSession.uploadAllLocalChangesOrFail() - } - assertTrue(customLogger.logs.isNotEmpty()) - assertTrue(customLogger.logs.any { it.contains("Connection[1]: Negotiated protocol version:") }, "Missing Connection[1]") - } - } - // This test verifies that the user facing Realm instance is actually advanced on an on-needed // basis even though there is no actual listener or explicit await download/upload calls. @Test @@ -1865,7 +1825,6 @@ class SyncedRealmTests { partitionValue: String, name: String = DEFAULT_NAME, encryptionKey: ByteArray? = null, - log: LogConfiguration? = null, errorHandler: ErrorHandler? = null, schema: Set> = PARTITION_BASED_SCHEMA, block: SyncConfiguration.Builder.() -> Unit = {} @@ -1876,7 +1835,6 @@ class SyncedRealmTests { ).name(name).also { builder -> if (encryptionKey != null) builder.encryptionKey(encryptionKey) if (errorHandler != null) builder.errorHandler(errorHandler) - if (log != null) builder.log(log.level, log.loggers) block(builder) }.build() @@ -1885,7 +1843,6 @@ class SyncedRealmTests { user: User, name: String = DEFAULT_NAME, encryptionKey: ByteArray? = null, - log: LogConfiguration? = null, errorHandler: ErrorHandler? = null, schema: Set> = FLEXIBLE_SYNC_SCHEMA, initialSubscriptions: InitialSubscriptionsCallback? = null, @@ -1896,7 +1853,6 @@ class SyncedRealmTests { ).name(name).also { builder -> if (encryptionKey != null) builder.encryptionKey(encryptionKey) if (errorHandler != null) builder.errorHandler(errorHandler) - if (log != null) builder.log(log.level, log.loggers) if (initialSubscriptions != null) builder.initialSubscriptions(false, initialSubscriptions) block(builder) }.build() From 52c2921b8f47c35a32ac0e7a91f2033d2fe6b9ec Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 01:21:26 +0200 Subject: [PATCH 51/56] Update test cases --- .../kotlin/io/realm/kotlin/test/mongodb/TestApp.kt | 2 -- .../kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt | 8 ++++++-- .../mongodb/common/SyncClientResetIntegrationTests.kt | 8 ++------ 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt index 38c237c193..27ad338456 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt @@ -27,7 +27,6 @@ import io.realm.kotlin.internal.interop.sync.NetworkTransport import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.internal.platform.singleThreadDispatcher import io.realm.kotlin.log.LogLevel -import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.AppConfiguration import io.realm.kotlin.mongodb.Credentials @@ -103,7 +102,6 @@ open class TestApp private constructor( it.syncRootDirectory(PlatformUtils.createTempDir("$appName-$testId")) }, debug: Boolean = false, - customLogger: RealmLogger? = null, networkTransport: NetworkTransport? = null, ejson: EJson = EJson, initialSetup: suspend AppServicesClient.(app: BaasApp, service: Service) -> Unit = { app: BaasApp, service: Service -> diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt index bef3f11c9d..17bde55cd9 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@file:Suppress("invisible_reference", "invisible_member") package io.realm.kotlin.test.mongodb.common import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.log.LogCategory import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.log.RealmLog import io.realm.kotlin.log.RealmLogger import io.realm.kotlin.mongodb.Credentials import io.realm.kotlin.mongodb.GoogleAuthType @@ -112,7 +114,9 @@ class HttpLogObfuscatorTests { @BeforeTest fun setUp() { + RealmLog.level = LogLevel.DEBUG channel = Channel(1) + RealmLog.add(ObfuscatorLoggerInspector(channel)) } private fun initApp(): TestApp { @@ -120,7 +124,6 @@ class HttpLogObfuscatorTests { this::class.simpleName, appName = syncServerAppName("obfsctr"), logLevel = LogLevel.DEBUG, - customLogger = ObfuscatorLoggerInspector(channel), initialSetup = { app, service -> initializeDefault(app, service) app.addFunction(TestAppInitializer.FIRST_ARG_FUNCTION) @@ -133,6 +136,7 @@ class HttpLogObfuscatorTests { @AfterTest fun tearDown() { channel.close() + RealmLog.reset() if (this::app.isInitialized) { app.close() @@ -142,12 +146,12 @@ class HttpLogObfuscatorTests { @Test fun nullObfuscator() = runBlocking { val logger = CustomLogCollector() + RealmLog.add(logger) app = TestApp( "nullObfuscator", appName = syncServerAppName("null-obf"), logLevel = LogLevel.DEBUG, builder = { it.httpLogObfuscator(null) }, - customLogger = logger, initialSetup = { app, service -> initializeDefault(app, service) app.addFunction(TestAppInitializer.FIRST_ARG_FUNCTION) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt index 48675b733d..d5307a5c16 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt @@ -114,11 +114,11 @@ class SyncClientResetIntegrationTests { builder: SyncConfiguration.Builder ) -> Unit ) { + RealmLog.add(ClientResetLoggerInspector(logChannel)) val app = TestApp( this::class.simpleName, appName = appName, logLevel = LogLevel.INFO, - customLogger = ClientResetLoggerInspector(logChannel), initialSetup = { app, service -> addEmailProvider(app) when (syncMode) { @@ -332,20 +332,16 @@ class SyncClientResetIntegrationTests { } } - private lateinit var initialLogLevel: LogLevel private lateinit var partitionValue: String @BeforeTest fun setup() { - initialLogLevel = RealmLog.level partitionValue = TestHelper.randomPartitionValue() } @AfterTest fun tearDown() { - RealmLog.removeAll() - RealmLog.addDefaultSystemLogger() - RealmLog.level = initialLogLevel + RealmLog.reset() } // --------------------------------------------------------------------------------------- From 98741070ab6e8359c6660fc3787fb3049dd63e0e Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 01:46:23 +0200 Subject: [PATCH 52/56] Use context logger with app services client --- .../realm/kotlin/test/mongodb/util/HttpClient.kt | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt index edbcedb4af..61a9894bf2 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/util/HttpClient.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +@file:Suppress("invisible_reference", "invisible_member") package io.realm.kotlin.test.mongodb.util import io.ktor.client.HttpClient @@ -24,9 +24,8 @@ import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.logging.Logger import io.ktor.client.plugins.logging.Logging import io.ktor.serialization.kotlinx.json.json -import io.realm.kotlin.internal.platform.createDefaultSystemLogger -import io.realm.kotlin.log.LogCategory -import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.internal.ContextLogger +import io.realm.kotlin.mongodb.internal.LogObfuscatorImpl import io.realm.kotlin.mongodb.internal.createPlatformClient import kotlinx.serialization.json.Json import kotlin.time.Duration.Companion.seconds @@ -52,15 +51,12 @@ fun defaultClient(name: String, debug: Boolean, block: HttpClientConfig<*>.() -> ) } - // TODO figure out logging and obfuscating sensitive info - // https://github.com/realm/realm-kotlin/issues/410 if (debug) { install(Logging) { logger = object : Logger { - // TODO Hook up with AppConfiguration/RealmConfiguration logger - private val logger = createDefaultSystemLogger(name) + private val logger = ContextLogger(name) override fun log(message: String) { - logger.log(LogCategory.Realm.Sdk, LogLevel.DEBUG, throwable = null, message = message) + logger.debug(LogObfuscatorImpl.obfuscate(message)) } } level = io.ktor.client.plugins.logging.LogLevel.ALL From b1923addfe79adcc1b3f7e3e15b74dab9e43c46e Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 09:10:49 +0200 Subject: [PATCH 53/56] Remove obsolete code --- .../io/realm/kotlin/test/mongodb/TestApp.kt | 1 - .../mongodb/common/HttpLogObfuscatorTests.kt | 2 -- .../common/SyncClientResetIntegrationTests.kt | 2 +- .../test/mongodb/common/SyncConfigTests.kt | 24 ------------------- .../test/mongodb/common/SyncedRealmTests.kt | 6 +++-- 5 files changed, 5 insertions(+), 30 deletions(-) diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt index 27ad338456..7d514c8c04 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt @@ -97,7 +97,6 @@ open class TestApp private constructor( testId: String?, appName: String = TEST_APP_PARTITION, dispatcher: CoroutineDispatcher = singleThreadDispatcher("$testId-dispatcher"), - logLevel: LogLevel? = LogLevel.WARN, builder: (AppConfiguration.Builder) -> AppConfiguration.Builder = { it.syncRootDirectory(PlatformUtils.createTempDir("$appName-$testId")) }, diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt index 17bde55cd9..b1a686baa9 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt @@ -123,7 +123,6 @@ class HttpLogObfuscatorTests { return TestApp( this::class.simpleName, appName = syncServerAppName("obfsctr"), - logLevel = LogLevel.DEBUG, initialSetup = { app, service -> initializeDefault(app, service) app.addFunction(TestAppInitializer.FIRST_ARG_FUNCTION) @@ -150,7 +149,6 @@ class HttpLogObfuscatorTests { app = TestApp( "nullObfuscator", appName = syncServerAppName("null-obf"), - logLevel = LogLevel.DEBUG, builder = { it.httpLogObfuscator(null) }, initialSetup = { app, service -> initializeDefault(app, service) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt index d5307a5c16..ede31b9391 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientResetIntegrationTests.kt @@ -114,11 +114,11 @@ class SyncClientResetIntegrationTests { builder: SyncConfiguration.Builder ) -> Unit ) { + RealmLog.setLevel(LogLevel.INFO) RealmLog.add(ClientResetLoggerInspector(logChannel)) val app = TestApp( this::class.simpleName, appName = appName, - logLevel = LogLevel.INFO, initialSetup = { app, service -> addEmailProvider(app) when (syncMode) { diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt index fc7a47893a..8a980677e5 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt @@ -1210,30 +1210,6 @@ class SyncConfigTests { assertTrue(config.syncClientResetStrategy is RecoverOrDiscardUnsyncedChangesStrategy) } - @Test - fun logLevelDoesNotGetOverwrittenByConfig() { - app.asTestApp.close() - // Prevent AppConfiguration to set a log level - app = TestApp("logLevelDoesNotGetOverwrittenByConfig", logLevel = null) - - val expectedLogLevel = LogLevel.ALL - - RealmLog.level = expectedLogLevel - - val (email, password) = randomEmail() to "password1234" - val user = runBlocking { - app.createUserAndLogIn(email, password) - } - - SyncConfiguration.Builder( - schema = FLEXIBLE_SYNC_SCHEMA, - user = user, - partitionValue = partitionValue - ).build() - - assertEquals(expectedLogLevel, RealmLog.level) - } - private fun createTestUser(): User = runBlocking { val (email, password) = randomEmail() to "password1234" app.createUserAndLogIn(email, password) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index a28962d787..48b5371e1b 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +@file:Suppress("invisible_reference", "invisible_member") package io.realm.kotlin.test.mongodb.common @@ -31,6 +32,7 @@ import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.log.LogLevel +import io.realm.kotlin.log.RealmLog import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.User import io.realm.kotlin.mongodb.exceptions.DownloadingRealmTimeOutException @@ -137,6 +139,8 @@ class SyncedRealmTests { if (this::app.isInitialized) { app.asTestApp.close() } + + RealmLog.reset() } @Test @@ -1067,7 +1071,6 @@ class SyncedRealmTests { fun writeCopyTo_flexibleSyncToFlexibleSync() = runBlocking { TestApp( "writeCopyTo_flexibleSyncToFlexibleSync", - logLevel = io.realm.kotlin.log.LogLevel.ALL, appName = io.realm.kotlin.test.mongodb.TEST_APP_FLEX, builder = { it.syncRootDirectory(PlatformUtils.createTempDir("flx-sync-")) @@ -1362,7 +1365,6 @@ class SyncedRealmTests { fun createInitialRealmFx() = runBlocking { TestApp( "createInitialRealmFx", - logLevel = LogLevel.ALL, appName = io.realm.kotlin.test.mongodb.TEST_APP_FLEX, builder = { it.syncRootDirectory(PlatformUtils.createTempDir("flx-sync-")) From 215304331cc0416aa80e32a89f390b2377bb3864 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 09:11:31 +0200 Subject: [PATCH 54/56] Linting --- .../commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt | 1 - .../io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt | 1 - .../io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt index 7d514c8c04..4af35452e4 100644 --- a/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt +++ b/packages/test-sync/src/commonMain/kotlin/io/realm/kotlin/test/mongodb/TestApp.kt @@ -26,7 +26,6 @@ import io.realm.kotlin.internal.interop.SynchronizableObject import io.realm.kotlin.internal.interop.sync.NetworkTransport import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.internal.platform.singleThreadDispatcher -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.AppConfiguration import io.realm.kotlin.mongodb.Credentials diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt index 8a980677e5..d3867e1d11 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncConfigTests.kt @@ -32,7 +32,6 @@ import io.realm.kotlin.ext.query import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.internal.platform.singleThreadDispatcher -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.User diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index 48b5371e1b..51f3c65f3a 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -31,7 +31,6 @@ import io.realm.kotlin.ext.query import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking -import io.realm.kotlin.log.LogLevel import io.realm.kotlin.log.RealmLog import io.realm.kotlin.mongodb.App import io.realm.kotlin.mongodb.User From 123d59d1e7d24fb47051091568a5d3897ae8c020 Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 12:36:00 +0200 Subject: [PATCH 55/56] Pr review changes --- CHANGELOG.md | 5 +- buildSrc/src/main/kotlin/Config.kt | 2 +- .../io/realm/kotlin/internal/ContextLogger.kt | 2 +- .../io/realm/kotlin/internal/LogUtils.kt | 1 + .../kotlin/io/realm/kotlin/log/LogCategory.kt | 7 --- .../kotlin/io/realm/kotlin/log/LogLevel.kt | 2 +- .../kotlin/io/realm/kotlin/log/RealmLog.kt | 17 ++---- .../mongodb/internal/RealmSyncInitializer.kt | 2 +- .../test/common/RealmConfigurationTests.kt | 6 +- .../realm/kotlin/test/common/RealmLogTests.kt | 60 ++++--------------- .../test/common/VersionTrackingTests.kt | 4 +- .../mongodb/common/AppConfigurationTests.kt | 18 +----- .../kotlin/test/mongodb/common/AppTests.kt | 2 +- .../mongodb/common/HttpLogObfuscatorTests.kt | 2 +- 14 files changed, 37 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9ea6a516b..dc41a998ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,11 @@ -## 1.17.0-SNAPSHOT (YYYY-MM-DD) +## 2.0.0-SNAPSHOT (YYYY-MM-DD) [!NOTE] This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from file format v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible. ### Breaking changes -* None. +* Removed property `RealmLog.level`. Log levels can be set with `RealmLog.setLevel`. (Issue [#1691](https://github.com/realm/realm-kotlin/issues/1691) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1038)) +* Removed `LogConfiguration`. Log levels and custom loggers can be set with `RealmLog`. (Issue [#1691](https://github.com/realm/realm-kotlin/issues/1691) [JIRA](https://jira.mongodb.org/browse/RKOTLIN-1038)) ### Enhancements * Support for RealmLists and RealmDictionaries in `RealmAny`. (Issue [#1434](https://github.com/realm/realm-kotlin/issues/1434)) diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index 819ab881c4..4ef9f452bf 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -62,7 +62,7 @@ val HOST_OS: OperatingSystem = findHostOs() object Realm { val ciBuild = (System.getenv("CI") != null) - const val version = "1.17.0-SNAPSHOT" + const val version = "2.0.0-SNAPSHOT" const val group = "io.realm.kotlin" const val projectUrl = "https://realm.io" const val pluginPortalId = "io.realm.kotlin" diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt index 2b1efbc1b1..4b4231a8fa 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/ContextLogger.kt @@ -85,7 +85,7 @@ public class ContextLogger(public val context: String? = null) { level: LogLevel, block: () -> Unit, ) { - if (level.priority >= RealmLog.getLevel(SdkLogCategory).priority) { + if (level.priority >= RealmLog.sdkLogLevel.priority) { block() } } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt index 39630dfda9..6255540ce4 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/LogUtils.kt @@ -57,6 +57,7 @@ internal fun newCategory( } // at package level as a workaround to ensure compatibility with darwin and jvm +// safe to use because it is loaded during class loading. internal val categoriesByPath: MutableMap = mutableMapOf() internal fun messageWithCategory( diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt index 5f273d958f..4760ee9b12 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogCategory.kt @@ -19,13 +19,6 @@ package io.realm.kotlin.log import io.realm.kotlin.internal.categoriesByPath import io.realm.kotlin.internal.newCategory -/* - * Core does not expose the different categories in compile time. - * - * This LogCategory design tries to overcome this issue by expressing the categories hierarchy - * in the kotlin type system, then validate it with a test watchdog. - */ - /** * Defines a log category for the Realm logger. */ diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt index fc1d2a89b0..563c57fdef 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/LogLevel.kt @@ -23,7 +23,7 @@ import io.realm.kotlin.log.LogLevel.WTF * Enum describing the log levels available to the Realm logger. * * Each log entry is assigned a priority between [TRACE] and [WTF]. If the log level is equal or - * higher than the priority defined in [RealmLog.level] the event will be logged. + * higher than the priority defined in [RealmLog.getLevel] the event will be logged. */ @Suppress("MagicNumber") public enum class LogLevel(public val priority: Int) { diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt index 9705c0d79d..5b066e57b0 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/log/RealmLog.kt @@ -44,7 +44,7 @@ public object RealmLog { private val loggersMutex = SynchronizableObject() // Reference to the currently installed system logger (if any) // `internal` until we can remove the old log API - internal var systemLoggerInstalled: RealmLogger? = null + private var systemLoggerInstalled: RealmLogger? = null // Kotlin Multiplatform is currently lacking primitives like CopyOnWriteArrayList. We could // use `io.realm.kotlin.internal.interop.SynchronizableObject`, but it would require locking // when reporting a log statement which feel a bit heavy, so instead we have added locks around @@ -55,14 +55,8 @@ public object RealmLog { // Log level that would be set by default private val defaultLogLevel = LogLevel.WARN - /** - * The current [LogLevel]. Changing this will affect all registered loggers. - */ - public var level: LogLevel - get() = getLevel(LogCategory.Realm) - set(value) { - setLevel(value, LogCategory.Realm) - } + // Cached value of the SDK log level + internal var sdkLogLevel = defaultLogLevel /** * Sets the log level of a log category. By setting the log level of a category all its subcategories @@ -73,6 +67,7 @@ public object RealmLog { */ public fun setLevel(level: LogLevel, category: LogCategory = LogCategory.Realm) { RealmInterop.realm_set_log_level_category(category.toString(), level.toCoreLogLevel()) + sdkLogLevel = getLevel(SdkLogCategory) } /** @@ -81,7 +76,7 @@ public object RealmLog { * @param category target log category. * @return current [category] log level. */ - public fun getLevel(category: LogCategory): LogLevel { + public fun getLevel(category: LogCategory = LogCategory.Realm): LogLevel { return RealmInterop.realm_get_log_level_category(category.toString()).fromCoreLogLevel() } @@ -201,6 +196,6 @@ public object RealmLog { internal fun reset() { removeAll() addDefaultSystemLogger() - level = LogLevel.WARN + setLevel(LogLevel.WARN) } } diff --git a/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt b/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt index c91070d5f3..2217071573 100644 --- a/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt +++ b/packages/library-sync/src/androidMain/kotlin/io/realm/kotlin/mongodb/internal/RealmSyncInitializer.kt @@ -38,7 +38,7 @@ import io.realm.kotlin.internal.RealmInitializer internal class RealmSyncInitializer : Initializer { companion object { - val logger: ContextLogger = ContextLogger() + val logger: ContextLogger = ContextLogger("RealmSyncInitializer") @Suppress("DEPRECATION") // Should only be called below API 21 fun isConnected(cm: ConnectivityManager?): Boolean { diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt index 2d3bbabf6f..e45b2c5c67 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmConfigurationTests.kt @@ -450,14 +450,14 @@ class RealmConfigurationTests { @Test fun logLevelDoesNotGetOverwrittenByConfig() { val expectedLogLevel = LogLevel.ALL - RealmLog.level = expectedLogLevel + RealmLog.setLevel(expectedLogLevel) - assertEquals(expectedLogLevel, RealmLog.level) + assertEquals(expectedLogLevel, RealmLog.getLevel()) RealmConfiguration.Builder(setOf(Sample::class)) .build() - assertEquals(expectedLogLevel, RealmLog.level) + assertEquals(expectedLogLevel, RealmLog.getLevel()) RealmLog.reset() } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 8846d54dcf..2d1c219f61 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -50,22 +50,24 @@ class RealmLogTests { @BeforeTest fun setUp() { - existingLogLevel = RealmLog.level - RealmLog.level = LogLevel.ALL + existingLogLevel = RealmLog.getLevel() } @AfterTest fun tearDown() { - RealmLog.level = existingLogLevel - RealmLog.removeAll() - RealmLog.addDefaultSystemLogger() + RealmLog.reset() + } + + @Test + fun defaultLevel() { + assertEquals(LogLevel.WARN, existingLogLevel) } @Test fun ignoreEventsLowerThanLogLevel() { val customLogger = TestLogger() RealmLog.apply { - level = LogLevel.WARN + setLevel(LogLevel.WARN) add(customLogger) log.warn("Testing 1") assertEquals("Testing 1", customLogger.message) @@ -79,7 +81,7 @@ class RealmLogTests { @Test fun customLogger() { val customLogger = TestLogger() - RealmLog.level = LogLevel.ALL + RealmLog.setLevel(LogLevel.ALL) RealmLog.add(customLogger) var message = "Testing" @@ -214,46 +216,6 @@ class RealmLogTests { } } - @Test - fun deprecatedMethodWork1() { - val called = atomic(false) - val customLogger = object : RealmLogger { - override fun log( - category: LogCategory, - level: LogLevel, - throwable: Throwable?, - message: String?, - vararg args: Any?, - ) { - assertEquals("Hello", message) - called.value = true - } - } - RealmLog.add(customLogger) - log.trace("Hello") - assertTrue(called.value) - } - - @Test - fun deprecatedMethodWork2() { - val called = atomic(false) - val customLogger = object : RealmLogger { - override fun log( - category: LogCategory, - level: LogLevel, - throwable: Throwable?, - message: String?, - vararg args: Any?, - ) { - assertEquals("Hello", message) - called.value = true - } - } - RealmLog.add(customLogger) - log.trace("Hello") - assertTrue(called.value) - } - @Test fun addLogger() { val called = atomic(false) @@ -393,6 +355,10 @@ class RealmLogTests { assertTrue(LogCategory.Realm.Storage.Transaction in LogCategory.Realm.Storage) } + /** + * Core defines the different categories in runtime, forcing the SDK to define the categories again. + * This test validates that we have defined the same categories as in Core. + */ @Test fun categoriesWatchdog() { val coreLogCategoryNames = RealmInterop.realm_get_category_names() diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt index 77fb6ed574..a33fa06d16 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/VersionTrackingTests.kt @@ -55,7 +55,7 @@ class VersionTrackingTests { @BeforeTest fun setup() { - initialLogLevel = RealmLog.level + initialLogLevel = RealmLog.getLevel() tmpDir = PlatformUtils.createTempDir() configuration = RealmConfiguration.Builder( schema = setOf( @@ -75,7 +75,7 @@ class VersionTrackingTests { realm.close() } PlatformUtils.deleteTempDir(tmpDir) - RealmLog.level = initialLogLevel + RealmLog.setLevel(initialLogLevel) } @Test diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt index a5ab7c7ff9..2239de354a 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppConfigurationTests.kt @@ -398,8 +398,8 @@ class AppConfigurationTests { } private suspend fun doCustomHeaderTest(app: App) { - val originalLevel = RealmLog.level - RealmLog.level = LogLevel.ALL + val originalLevel = RealmLog.getLevel() + RealmLog.setLevel(LogLevel.ALL) val channel = TestChannel() val logger = object : RealmLogger { @@ -434,22 +434,10 @@ class AppConfigurationTests { } finally { // Restore log status RealmLog.remove(logger) - RealmLog.level = originalLevel + RealmLog.setLevel(originalLevel) } } - @Test - fun logLevelDoesNotGetOverwrittenByConfig() { - val expectedLogLevel = LogLevel.ALL - RealmLog.level = expectedLogLevel - - AppConfiguration.create("") - - assertEquals(expectedLogLevel, RealmLog.level) - - RealmLog.reset() - } - @Test fun injectedBundleId() { val app = App.create(APP_ID) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppTests.kt index 576ab58307..de9d26aae5 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppTests.kt @@ -523,7 +523,7 @@ class AppTests { ).use { testApp -> assertEquals(SyncServerConfig.url, testApp.baseUrl) - RealmLog.level = LogLevel.ALL + RealmLog.setLevel(LogLevel.ALL) runBlocking { testApp.updateBaseUrl(null) } diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt index b1a686baa9..f72eba9784 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/HttpLogObfuscatorTests.kt @@ -114,7 +114,7 @@ class HttpLogObfuscatorTests { @BeforeTest fun setUp() { - RealmLog.level = LogLevel.DEBUG + RealmLog.setLevel(LogLevel.DEBUG) channel = Channel(1) RealmLog.add(ObfuscatorLoggerInspector(channel)) } From 718d042b50af40e9d3c34b0d04cccddc68af7bbb Mon Sep 17 00:00:00 2001 From: Clemente Date: Thu, 16 May 2024 23:15:00 +0200 Subject: [PATCH 56/56] Set log level for RealmLogTests --- .../kotlin/io/realm/kotlin/test/common/RealmLogTests.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt index 2d1c219f61..e8a321b316 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmLogTests.kt @@ -51,6 +51,7 @@ class RealmLogTests { @BeforeTest fun setUp() { existingLogLevel = RealmLog.getLevel() + RealmLog.setLevel(LogLevel.ALL) } @AfterTest