From b8cbf7bb15c9873103689050558640761bf9135a Mon Sep 17 00:00:00 2001 From: renwj Date: Tue, 31 Jan 2023 10:20:50 +0800 Subject: [PATCH] =?UTF-8?q?[dev=5Farch=5Fopt=5F3.0]Apm=E4=B8=8A=E4=BC=A0AP?= =?UTF-8?q?PID=E4=B8=8EDocker=E7=89=88=E6=9C=AC=E5=8F=8A=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E7=8E=AF=E5=A2=83=E7=BB=91=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DevaToolsProvider.kt | 12 ++ .../apm/ApmEnvProviderImpl.kt | 133 ++++++++++++++++++ .../apm/config/ApmEnvConfig.kt | 51 +++++++ .../src/main/proto/apm_env.proto | 27 ++++ .../api/devatools/IDevaToolsProvider.kt | 3 + .../api/devatools/apm/IApmEnvProvider.kt | 10 ++ .../call/devatools/CallerDevaToolsManager.kt | 3 + test/crashreport-apmbyte/build.gradle | 2 + .../apm/ApmCrashReportProvider.java | 14 +- 9 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/ApmEnvProviderImpl.kt create mode 100644 core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/config/ApmEnvConfig.kt create mode 100644 core/function-impl/mogo-core-function-devatools/src/main/proto/apm_env.proto create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/apm/IApmEnvProvider.kt diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt index f988d43fcb..4dbc384f01 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt @@ -15,7 +15,9 @@ import com.mogo.eagle.core.data.deva.scene.SceneModule import com.mogo.eagle.core.data.deva.scene.SceneTAG import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider +import com.mogo.eagle.core.function.api.devatools.apm.* import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.zhjt.mogo_core_function_devatools.apm.* import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseConfig import com.zhjt.mogo_core_function_devatools.binding.BindingCarManager.Companion.bindingCarManager @@ -44,6 +46,11 @@ class DevaToolsProvider : IDevaToolsProvider { private var mContext: Context? = null + private val apmEnvProvider by lazy { ApmEnvProviderImpl } + + @Volatile + private var mDockerVersion: String? = null + override fun init(context: Context) { mContext = context } @@ -63,6 +70,7 @@ class DevaToolsProvider : IDevaToolsProvider { iPCReportManager.initServer() moFangManager.init(mContext!!) bindingCarManager.init(mContext!!) + apmEnvProvider.init(if(DebugConfig.isDebug()) "0" else "1", "${ DebugConfig.getNetMode() }", mDockerVersion ?: "") } override fun checkMonitorDb() { @@ -200,10 +208,13 @@ class DevaToolsProvider : IDevaToolsProvider { } override fun envConfigChange(cityCode: String, netMode: Int) { + apmEnvProvider.onEnvChanged(if(DebugConfig.isDebug()) "0" else "1", "${ DebugConfig.getNetMode() }", mDockerVersion ?: "") EnvChangeManager.changeTo(cityCode, netMode) } override fun dockerVersion(dockerVersion: String?) { + mDockerVersion = dockerVersion + apmEnvProvider.onEnvChanged(if(DebugConfig.isDebug()) "0" else "1","${ DebugConfig.getNetMode() }", dockerVersion ?: "") BadCaseConfig.dockerVersion = dockerVersion } @@ -227,4 +238,5 @@ class DevaToolsProvider : IDevaToolsProvider { bindingCarManager.queryAppUpgrade() } + override fun apmEnvProvider(): IApmEnvProvider = apmEnvProvider } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/ApmEnvProviderImpl.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/ApmEnvProviderImpl.kt new file mode 100644 index 0000000000..1a6a181a80 --- /dev/null +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/ApmEnvProviderImpl.kt @@ -0,0 +1,133 @@ +package com.zhjt.mogo_core_function_devatools.apm + +import android.os.Process +import android.text.TextUtils +import android.util.* +import android.widget.Toast +import com.mogo.commons.debug.DebugConfig +import com.mogo.eagle.core.function.api.devatools.apm.* +import com.mogo.eagle.core.utilcode.util.* +import com.zhjt.mogo_core_function_devatools.apm.config.* +import kotlinx.coroutines.* +import java.util.concurrent.atomic.AtomicBoolean +import java.util.concurrent.atomic.AtomicReference +import kotlin.coroutines.* + +object ApmEnvProviderImpl: IApmEnvProvider, CoroutineScope { + + private const val TAG = "ApmEnvProvider" + + private val scope by lazy { CoroutineScope(Dispatchers.IO + SupervisorJob()) } + + private val hasInit by lazy { AtomicBoolean(false) } + + private val mBuildType by lazy { AtomicReference() } + private val mNetType by lazy { AtomicReference() } + private val mDockerVersion by lazy { AtomicReference() } + + override val coroutineContext: CoroutineContext + get() = scope.coroutineContext + + override fun init(buildType: String, netType: String, dockerVersion: String) { + launch { + if (ApmEnvConfig.isFirstEnter()) { + if (!TextUtils.isEmpty(buildType)) { + ApmEnvConfig.setBuildType(buildType) + } + if (!TextUtils.isEmpty(netType)) { + ApmEnvConfig.setNetType(netType) + } + if (!TextUtils.isEmpty(dockerVersion)) { + ApmEnvConfig.setDockerVersion(dockerVersion) + } + } + hasInit.set(true) + } + } + + override fun onEnvChanged(buildType: String, netType: String, dockerVersion: String) { + if (!hasInit.get()) { + return + } + if (mBuildType.get() == buildType && mNetType.get() == netType && mDockerVersion.get() == dockerVersion) { + return + } + launch { + Log.d(TAG, "onEnvChanged[1]:[buildType: $buildType, netType:$netType, dockerVersion:$dockerVersion]") + var buildTypeChanged = false + if (ApmEnvConfig.getBuildType() != buildType) { + buildTypeChanged = true + ApmEnvConfig.setBuildType(buildType) + } + var netTypeChanged = false + if (ApmEnvConfig.getNetType() != netType) { + netTypeChanged = true + ApmEnvConfig.setNetType(netType) + } + var dockerVersionChanged = false + val version = ApmEnvConfig.getDockerVersion() + if (!TextUtils.isEmpty(version) && !TextUtils.isEmpty(dockerVersion) && version != dockerVersion) { + dockerVersionChanged = true + ApmEnvConfig.setDockerVersion(dockerVersion) + } + var isFirstDockerVersionSet = false + if (TextUtils.isEmpty(version) && !TextUtils.isEmpty(dockerVersion)) { + isFirstDockerVersionSet = true + ApmEnvConfig.setDockerVersion(dockerVersion) + } + var isEnvValid = true + if (dockerVersionChanged || isFirstDockerVersionSet) { + isEnvValid = buildType == "0" || (buildType == "1" && netType == DebugConfig.NET_MODE_RELEASE.toString() && dockerVersion.endsWith("release", true)) + } + val appRelaunched = ApmEnvConfig.isAppRelaunched() + Log.d(TAG, "onEnvChanged[2]: buildTypeChanged: $buildTypeChanged, netTypeChanged: $netTypeChanged, dockerVersionChanged:$dockerVersionChanged], isAppLaunched:$appRelaunched") + if ((!isEnvValid || (buildTypeChanged || netTypeChanged || dockerVersionChanged)) && !appRelaunched) { + ApmEnvConfig.setAppRelaunched(true) + restartApp() + return@launch + } + if (isFirstDockerVersionSet) { + return@launch + } + + if (appRelaunched) { + ApmEnvConfig.setAppRelaunched(false) + } + + if (!TextUtils.isEmpty(buildType)) { + mBuildType.set(buildType) + } + + if (!TextUtils.isEmpty(netType)) { + mNetType.set(netType) + } + + if (!TextUtils.isEmpty(dockerVersion)) { + mDockerVersion.set(dockerVersion) + } + } + } + + private fun restartApp() { + launch(Dispatchers.Main) { + Log.d(TAG, "restartApp ---") + Toast.makeText(Utils.getApp(), "发现系统环境不一致,正在重启...", Toast.LENGTH_SHORT).show() + delay(50) + Utils.getApp().startActivity(Utils.getApp().packageManager.getLaunchIntentForPackage(Utils.getApp().packageName)) + Process.killProcess(Process.myPid()) + } + } + + override fun isDebugEnabled(): Boolean? { + return runBlocking { + val oldBuildType = ApmEnvConfig.getBuildType() + val oldNetType = ApmEnvConfig.getNetType() + val oldDockerVersion = ApmEnvConfig.getDockerVersion() + if (TextUtils.isEmpty(oldBuildType) || TextUtils.isEmpty(oldNetType) || TextUtils.isEmpty(oldDockerVersion)) { + null + } else { + DebugConfig.isDebug() || (oldBuildType != "1" || oldNetType != DebugConfig.NET_MODE_RELEASE.toString() || !(oldDockerVersion?.endsWith("release", true) ?: false)) + } + } + } +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/config/ApmEnvConfig.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/config/ApmEnvConfig.kt new file mode 100644 index 0000000000..66541f4bf9 --- /dev/null +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/apm/config/ApmEnvConfig.kt @@ -0,0 +1,51 @@ +package com.zhjt.mogo_core_function_devatools.apm.config + +import androidx.datastore.core.* +import com.mogo.eagle.core.utilcode.util.Utils +import com.zhjt.mogo_core_function_devatools.apm.generated.ApmEnv +import kotlinx.coroutines.* +import kotlinx.coroutines.flow.* +import java.io.* + +object ApmEnvConfig { + + private val serializer = object : Serializer { + + override val defaultValue: ApmEnv + get() = ApmEnv.getDefaultInstance() + + override suspend fun readFrom(input: InputStream): ApmEnv { + return withContext(Dispatchers.IO) { + ApmEnv.parseFrom(input) + } + } + + override suspend fun writeTo(t: ApmEnv, output: OutputStream) { + withContext(Dispatchers.IO) { + t.writeTo(output) + } + } + } + + private val store: DataStore by lazy { + DataStoreFactory.create(serializer) { File(Utils.getApp().filesDir, "apm_env.pb")} + } + + suspend fun isFirstEnter() = store.data.firstOrNull()?.let { it.buildType.isNullOrEmpty() || it.netType.isNullOrEmpty() || it.dockerVersion.isNullOrEmpty() } ?: true + + suspend fun setBuildType(type: String) = store.updateData { it.toBuilder().setBuildType(type).build() } + + suspend fun setDockerVersion(version: String) = store.updateData { it.toBuilder().setDockerVersion(version).build() } + + suspend fun setNetType(type: String) = store.updateData { it.toBuilder().setNetType(type).build() } + + suspend fun getBuildType(): String? = store.data.catch { if (it is IOException) emit(ApmEnv.getDefaultInstance()) }.map { it.buildType }.firstOrNull() + + suspend fun getDockerVersion(): String? = store.data.catch { if (it is IOException) emit(ApmEnv.getDefaultInstance()) }.map { it.dockerVersion }.firstOrNull() + + suspend fun getNetType(): String? = store.data.catch { if (it is IOException) emit(ApmEnv.getDefaultInstance()) }.map { it.netType }.firstOrNull() + + suspend fun setAppRelaunched(isReLaunched: Boolean) = store.updateData { it.toBuilder().setIsRelaunchApp(isReLaunched).build() } + + suspend fun isAppRelaunched(): Boolean = store.data.catch { if (it is IOException) emit(ApmEnv.getDefaultInstance()) }.map { it.isRelaunchApp }.firstOrNull() ?: false +} \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/proto/apm_env.proto b/core/function-impl/mogo-core-function-devatools/src/main/proto/apm_env.proto new file mode 100644 index 0000000000..43fa9fd128 --- /dev/null +++ b/core/function-impl/mogo-core-function-devatools/src/main/proto/apm_env.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "com.zhjt.mogo_core_function_devatools.apm.generated"; + + +message ApmEnv { + + /** + * 构建类型: release:1; debug:0 + */ + string buildType = 1; + + /** + * 网络类型: 1:dev; 2: qa; 3: online; 4: demo + */ + string netType = 2; + /** + * docker版本 + */ + string dockerVersion = 3; + + /** + * 是否重启了应用 + */ + bool isRelaunchApp = 4; +} \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt index e11938e4bc..8a2650d7a0 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt @@ -11,6 +11,7 @@ import com.mogo.eagle.core.data.deva.chain.ChainLogParam import com.mogo.eagle.core.data.deva.scene.SceneModule import com.mogo.eagle.core.data.deva.scene.SceneTAG import com.mogo.eagle.core.data.msgbox.MsgBoxBean +import com.mogo.eagle.core.function.api.devatools.apm.* /** * 开发套件工具接口 @@ -182,4 +183,6 @@ interface IDevaToolsProvider : IProvider { fun envConfigChange(cityCode: String, netMode: Int) fun dockerVersion(dockerVersion: String?) + + fun apmEnvProvider(): IApmEnvProvider } \ No newline at end of file diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/apm/IApmEnvProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/apm/IApmEnvProvider.kt new file mode 100644 index 0000000000..9a4b98bcc8 --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/apm/IApmEnvProvider.kt @@ -0,0 +1,10 @@ +package com.mogo.eagle.core.function.api.devatools.apm + +interface IApmEnvProvider { + + fun init(buildType: String, netType: String, dockerVersion: String) + + fun onEnvChanged(buildType: String, netType: String, dockerVersion: String) + + fun isDebugEnabled(): Boolean? +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt index 37adbfcb54..77c4892197 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt @@ -13,6 +13,7 @@ import com.mogo.eagle.core.data.deva.scene.SceneModule import com.mogo.eagle.core.data.deva.scene.SceneTAG import com.mogo.eagle.core.data.msgbox.MsgBoxBean import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider +import com.mogo.eagle.core.function.api.devatools.apm.* import com.mogo.eagle.core.function.call.base.CallerBase import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils @@ -234,4 +235,6 @@ object CallerDevaToolsManager { fun queryAppUpgrade(){ devaToolsProviderApi?.queryAppUpgrade() } + + fun apmEnvProvider(): IApmEnvProvider? = devaToolsProviderApi?.apmEnvProvider() } \ No newline at end of file diff --git a/test/crashreport-apmbyte/build.gradle b/test/crashreport-apmbyte/build.gradle index d3c9f93c1e..eeab9e0aa8 100644 --- a/test/crashreport-apmbyte/build.gradle +++ b/test/crashreport-apmbyte/build.gradle @@ -54,10 +54,12 @@ dependencies { api rootProject.ext.dependencies.crashreport implementation rootProject.ext.dependencies.mogo_core_utils implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogo_core_function_call } else { api project(":test:crashreport") implementation project(':core:mogo-core-utils') implementation project(":foudations:mogo-commons") + implementation project(':core:mogo-core-function-call') } } diff --git a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java index ac143c2920..40bab898f4 100644 --- a/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java +++ b/test/crashreport-apmbyte/src/main/java/com/mogo/test/crashreport/apm/ApmCrashReportProvider.java @@ -1,6 +1,7 @@ package com.mogo.test.crashreport.apm; import android.content.Context; +import android.util.Log; import com.alibaba.android.arouter.facade.annotation.Route; import com.apm.insight.AttachUserData; @@ -14,6 +15,8 @@ import com.mogo.commons.constants.SharedPrefsConstants; import com.mogo.commons.debug.DebugConfig; import com.mogo.eagle.core.data.bindingcar.CarInfo; import com.mogo.eagle.core.data.config.FunctionBuildConfig; +import com.mogo.eagle.core.function.api.devatools.apm.IApmEnvProvider; +import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager; import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; import com.mogo.eagle.core.utilcode.mogo.storage.SharedPrefsMgr; @@ -52,7 +55,16 @@ public class ApmCrashReportProvider implements ITestCrashReportProvider { } private void initCrash(final Context context) { - MonitorCrash crash = MonitorCrash.init(context, DebugConfig.isDebug() ? BYTEAMP_APPID_DEV : BYTEAMP_APPID, CommonUtils.getVersionCode(context), CommonUtils.getVersionName(context)) + IApmEnvProvider provider = CallerDevaToolsManager.INSTANCE.apmEnvProvider(); + boolean isDebug = DebugConfig.isDebug(); + if (provider != null) { + Boolean enabled = provider.isDebugEnabled(); + Log.d("ApmCrashReportProvider", "--- isDebugEnabled:" + enabled); + if (enabled != null) { + isDebug = enabled; + } + } + MonitorCrash crash = MonitorCrash.init(context, isDebug ? BYTEAMP_APPID_DEV : BYTEAMP_APPID, CommonUtils.getVersionCode(context), CommonUtils.getVersionName(context)) .setCustomDataCallback(new AttachUserData() { @Override public Map getUserData(CrashType type) {