[dev_arch_opt_3.0]Apm上传APPID与Docker版本及服务端环境绑定

This commit is contained in:
renwj
2023-01-31 10:20:50 +08:00
parent 552b1e0e45
commit b8cbf7bb15
9 changed files with 254 additions and 1 deletions

View File

@@ -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
}

View File

@@ -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<String>() }
private val mNetType by lazy { AtomicReference<String>() }
private val mDockerVersion by lazy { AtomicReference<String>() }
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))
}
}
}
}

View File

@@ -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<ApmEnv> {
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<ApmEnv> 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
}

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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?
}

View File

@@ -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()
}

View File

@@ -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')
}
}

View File

@@ -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<? extends String, ? extends String> getUserData(CrashType type) {